#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
GUI编辑器模块
用于可视化编辑CEGUI布局文件
"""

import os
import sys
import glob
import traceback
import xml.etree.ElementTree as ET
from xml.dom import minidom

try:
    print("开始导入PyQt5模块...")
    from PyQt5.QtWidgets import (QMainWindow, QWidget, QApplication, QVBoxLayout, QHBoxLayout, 
                               QSplitter, QTreeWidget, QTreeWidgetItem, QTabWidget, QLabel, 
                               QLineEdit, QSpinBox, QDoubleSpinBox, QComboBox, QPushButton, 
                               QFileDialog, QMessageBox, QAction, QMenuBar, QMenu, QToolBar, 
                               QDockWidget, QGroupBox, QFormLayout, QCheckBox, QScrollArea, QActionGroup,
                               QDialog, QTextEdit, QGridLayout, QRadioButton, QShortcut)
    from PyQt5.QtCore import Qt, QPoint, QRect, QSize, pyqtSignal, QMimeData, QTimer
    from PyQt5.QtGui import QPixmap, QPainter, QColor, QPen, QDrag, QIcon, QImage, QFont
    print("PyQt5模块导入成功.")
    
    print("开始导入自定义模块...")
    print(f"当前工作目录: {os.getcwd()}")
    print(f"Python路径: {sys.path}")
    
    try:
        from xml_handler import XMLHandler
        print("xml_handler模块导入成功.")
    except ImportError as e:
        print(f"导入xml_handler失败: {e}")
        traceback.print_exc()
        
    try:    
        from custom_widgets import PropertyEditor, LayoutCanvas, ImagesetViewer
        print("custom_widgets模块导入成功.")
    except ImportError as e:
        print(f"导入custom_widgets失败: {e}")
        traceback.print_exc()
        
    try:
        from config_manager import ConfigManager
        print("config_manager模块导入成功.")
    except ImportError as e:
        print(f"导入config_manager失败: {e}")
        traceback.print_exc()
        
    print("所有模块导入成功.")
    
except Exception as e:
    print(f"初始化过程中出错: {e}")
    traceback.print_exc()
    input("按任意键退出...")
    sys.exit(1)

class MainWindow(QMainWindow):
    """主窗口类"""
    
    def __init__(self):
        super(MainWindow, self).__init__()
        self.xml_handler = XMLHandler()
        self.config_manager = ConfigManager()
        self.init_ui()
        self.current_layout_file = None
        self.is_layout_modified = False  # 记录布局是否被修改
        
        # 添加坐标模式管理
        self.coordinate_mode = 'relative'  # 'relative' 或 'absolute'
        
        # 加载配置
        self.load_config()
        
    def init_ui(self):
        """初始化UI"""
        # 设置窗口属性
        self.setWindowTitle('CEGUI布局编辑器')
        self.setGeometry(100, 100, 1200, 800)
        
        # 创建菜单栏
        self.create_menu_bar()
        
        # 创建工具栏
        self.create_tool_bar()
        
        # 创建中央窗口部件
        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)
        
        # 创建主布局
        self.main_layout = QHBoxLayout(self.central_widget)
        self.main_layout.setContentsMargins(2, 2, 2, 2)
        self.main_layout.setSpacing(2)
        
        # 创建主分割器
        self.main_splitter = QSplitter(Qt.Horizontal)
        self.main_layout.addWidget(self.main_splitter)
        
        # 创建左侧窗口部件(元素树)
        self.create_left_panel()
        
        # 创建中间窗口部件(编辑画布)
        self.create_center_panel()
        
        # 创建右侧窗口部件(属性编辑器)
        self.create_right_panel()
        
        # 创建状态栏
        self.statusBar().showMessage('就绪')
        
        # 连接信号与槽
        self.connect_signals_slots()

        # 添加XML查看对话框
        self.xml_view_dialog = None
        
        # 创建"最近打开"菜单
        self.create_recent_files_menu()
        
        # 设置分割器默认大小
        self.main_splitter.setSizes([200, 700, 300])  # 左侧树、中间画布、右侧属性编辑器
        
        # 添加全局快捷键
        self.create_shortcuts()
    
    def create_menu_bar(self):
        """创建菜单栏"""
        menubar = self.menuBar()
        
        # 文件菜单
        file_menu = menubar.addMenu('文件')
        
        new_action = QAction('新建', self)
        new_action.setShortcut('Ctrl+N')
        new_action.triggered.connect(self.new_layout)
        file_menu.addAction(new_action)
        
        open_action = QAction('打开布局', self)
        open_action.setShortcut('Ctrl+O')
        open_action.triggered.connect(self.open_layout)
        file_menu.addAction(open_action)
        
        # 添加"最近打开"子菜单
        self.recent_menu = QMenu('最近打开', self)
        file_menu.addMenu(self.recent_menu)
        
        # 添加设置根目录的菜单项
        set_root_dir_action = QAction('设置工程根目录', self)
        set_root_dir_action.triggered.connect(self.set_root_directory)
        file_menu.addAction(set_root_dir_action)
        
        file_menu.addSeparator()
        
        save_action = QAction('保存', self)
        save_action.setShortcut('Ctrl+S')
        save_action.triggered.connect(self.save_layout)
        file_menu.addAction(save_action)
        
        save_as_action = QAction('另存为', self)
        save_as_action.setShortcut('Ctrl+Shift+S')
        save_as_action.triggered.connect(self.save_layout_as)
        file_menu.addAction(save_as_action)
        
        file_menu.addSeparator()
        
        # 添加恢复原始文件选项
        restore_original_action = QAction('恢复为原始文件', self)
        restore_original_action.triggered.connect(self.restore_original_layout)
        file_menu.addAction(restore_original_action)
        
        file_menu.addSeparator()
        
        load_imageset_action = QAction('加载Imageset', self)
        load_imageset_action.triggered.connect(self.load_imageset)
        file_menu.addAction(load_imageset_action)
        
        # 添加设置imageset搜索目录的菜单项
        set_imageset_dir_action = QAction('设置Imageset搜索目录', self)
        set_imageset_dir_action.triggered.connect(self.set_imageset_search_dir)
        file_menu.addAction(set_imageset_dir_action)
        
        file_menu.addSeparator()
        
        exit_action = QAction('退出', self)
        exit_action.setShortcut('Ctrl+Q')
        exit_action.triggered.connect(self.close)
        file_menu.addAction(exit_action)
        
        # 编辑菜单
        edit_menu = menubar.addMenu('编辑')
        
        add_window_action = QAction('添加窗口', self)
        add_window_action.triggered.connect(self.add_window)
        edit_menu.addAction(add_window_action)
        
        delete_window_action = QAction('删除窗口', self)
        delete_window_action.triggered.connect(self.delete_window)
        edit_menu.addAction(delete_window_action)
        
        # 添加坐标转换器菜单项
        edit_menu.addSeparator()
        coordinate_converter_action = QAction('坐标转换器', self)
        coordinate_converter_action.triggered.connect(self.show_coordinate_converter)
        edit_menu.addAction(coordinate_converter_action)
        
        # 添加布局转换菜单项
        edit_menu.addSeparator()
        convert_to_1080p_action = QAction('转换为1080p', self)
        convert_to_1080p_action.triggered.connect(self.convert_to_1080p)
        edit_menu.addAction(convert_to_1080p_action)
        
        # 视图菜单
        view_menu = menubar.addMenu('视图')
        
        # 预览分辨率子菜单
        resolution_menu = QMenu('预览分辨率', self)
        
        resolution_800x600_action = QAction('800x600', self)
        resolution_800x600_action.setCheckable(True)
        resolution_800x600_action.setChecked(True)
        resolution_800x600_action.triggered.connect(lambda: self.set_preview_resolution(800, 600))
        resolution_menu.addAction(resolution_800x600_action)
        
        resolution_1024x768_action = QAction('1024x768', self)
        resolution_1024x768_action.setCheckable(True)
        resolution_1024x768_action.triggered.connect(lambda: self.set_preview_resolution(1024, 768))
        resolution_menu.addAction(resolution_1024x768_action)
        
        resolution_1280x720_action = QAction('1280x720', self)
        resolution_1280x720_action.setCheckable(True)
        resolution_1280x720_action.triggered.connect(lambda: self.set_preview_resolution(1280, 720))
        resolution_menu.addAction(resolution_1280x720_action)
        
        resolution_1920x1080_action = QAction('1920x1080', self)
        resolution_1920x1080_action.setCheckable(True)
        resolution_1920x1080_action.triggered.connect(lambda: self.set_preview_resolution(1920, 1080))
        resolution_menu.addAction(resolution_1920x1080_action)
        
        # 添加到视图菜单
        view_menu.addMenu(resolution_menu)
        
        # 创建分辨率操作组，确保只有一个选中
        self.resolution_action_group = QActionGroup(self)
        self.resolution_action_group.addAction(resolution_800x600_action)
        self.resolution_action_group.addAction(resolution_1024x768_action)
        self.resolution_action_group.addAction(resolution_1280x720_action)
        self.resolution_action_group.addAction(resolution_1920x1080_action)
        
        # 最终渲染模式选项
        view_menu.addSeparator()
        self.final_render_mode_action = QAction('使用最终渲染模式', self)
        self.final_render_mode_action.setCheckable(True)
        self.final_render_mode_action.triggered.connect(self.toggle_final_render_mode)
        view_menu.addAction(self.final_render_mode_action)
        
        # 添加只通过点击选择元素选项
        view_menu.addSeparator()
        self.click_select_only_action = QAction('只通过点击选择元素', self)
        self.click_select_only_action.setCheckable(True)
        self.click_select_only_action.setChecked(True)  # 默认启用
        self.click_select_only_action.triggered.connect(self.toggle_click_select_only)
        view_menu.addAction(self.click_select_only_action)
        
        # 添加坐标模式切换选项
        view_menu.addSeparator()
        self.coordinate_mode_action = QAction('使用绝对像素坐标', self)
        self.coordinate_mode_action.setCheckable(True)
        self.coordinate_mode_action.setChecked(False)  # 默认使用相对坐标
        self.coordinate_mode_action.triggered.connect(self.toggle_coordinate_mode)
        view_menu.addAction(self.coordinate_mode_action)
        
        # 帮助菜单
        help_menu = menubar.addMenu('帮助')
        
        about_action = QAction('关于', self)
        about_action.triggered.connect(self.show_about)
        help_menu.addAction(about_action)
    
    def create_tool_bar(self):
        """创建工具栏"""
        toolbar = self.addToolBar('工具栏')
        
        new_action = QAction('新建', self)
        new_action.triggered.connect(self.new_layout)
        toolbar.addAction(new_action)
        
        open_action = QAction('打开', self)
        open_action.triggered.connect(self.open_layout)
        toolbar.addAction(open_action)
        
        save_action = QAction('保存', self)
        save_action.triggered.connect(self.save_layout)
        toolbar.addAction(save_action)
        
        # 添加恢复原始文件按钮
        restore_original_action = QAction('恢复原始', self)
        restore_original_action.triggered.connect(self.restore_original_layout)
        toolbar.addAction(restore_original_action)
        
        toolbar.addSeparator()
        
        add_window_action = QAction('添加窗口', self)
        add_window_action.triggered.connect(self.add_window)
        toolbar.addAction(add_window_action)
        
        toolbar.addSeparator()
        
        # 添加转换布局按钮
        convert_to_1080p_action = QAction('转换为1080p', self)
        convert_to_1080p_action.triggered.connect(self.convert_to_1080p)
        toolbar.addAction(convert_to_1080p_action)
        
        toolbar.addSeparator()
        
        # 添加分辨率选择下拉框
        toolbar.addWidget(QLabel('预览分辨率:'))
        self.resolution_combo = QComboBox()
        self.resolution_combo.addItems(['800x600', '1024x768', '1280x720', '1920x1080'])
        self.resolution_combo.currentTextChanged.connect(self.on_resolution_changed)
        toolbar.addWidget(self.resolution_combo)
        
        toolbar.addSeparator()
        
        # 添加最终渲染模式选项
        self.final_render_checkbox = QCheckBox('最终渲染模式')
        self.final_render_checkbox.toggled.connect(self.toggle_final_render_mode)
        toolbar.addWidget(self.final_render_checkbox)
        
        toolbar.addSeparator()
        
        # 添加坐标模式切换选项
        self.coordinate_mode_checkbox = QCheckBox('绝对像素坐标')
        self.coordinate_mode_checkbox.toggled.connect(self.toggle_coordinate_mode)
        toolbar.addWidget(self.coordinate_mode_checkbox)
    
    def create_left_panel(self):
        """创建左侧窗口部件"""
        left_panel = QWidget()
        left_layout = QVBoxLayout(left_panel)
        left_layout.setContentsMargins(1, 1, 1, 1)
        
        # 创建文件列表面板
        self.create_file_lists_panel()
        
        # 创建元素树
        tree_label = QLabel('元素树:')
        self.element_tree = QTreeWidget()
        self.element_tree.setHeaderLabels(['名称', '可见性', '类型'])
        self.element_tree.setColumnWidth(0, 150)
        self.element_tree.setColumnWidth(1, 50)
        self.element_tree.setColumnWidth(2, 100)
        self.element_tree.itemClicked.connect(self.on_element_clicked)
        
        # 设置右键菜单
        self.element_tree.setContextMenuPolicy(Qt.CustomContextMenu)
        self.element_tree.customContextMenuRequested.connect(self.show_element_tree_menu)
        
        left_layout.addWidget(tree_label)
        left_layout.addWidget(self.element_tree)
        
        # 将左侧面板添加到主分割器
        self.main_splitter.addWidget(left_panel)
    
    def create_center_panel(self):
        """创建中央面板"""
        # 创建标签页控件
        self.tab_widget = QTabWidget()
        
        # 创建设计视图
        self.design_view = LayoutCanvas(self)
        self.tab_widget.addTab(self.design_view, '设计')
        
        # 创建XML视图
        self.xml_view = QWidget()
        self.xml_layout = QVBoxLayout(self.xml_view)
        
        # 创建XML文本编辑器
        self.xml_text_editor = QTextEdit()
        self.xml_text_editor.setReadOnly(True)  # 只读模式
        self.xml_text_editor.setLineWrapMode(QTextEdit.NoWrap)  # 不自动换行
        self.xml_text_editor.setFont(QFont("Courier New", 10))  # 使用等宽字体
        self.xml_layout.addWidget(self.xml_text_editor)
        
        # 将XML视图添加到标签页
        self.tab_widget.addTab(self.xml_view, 'XML')
        
        # 创建Imageset视图
        self.imageset_view = ImagesetViewer(self.xml_handler)
        self.tab_widget.addTab(self.imageset_view, 'Imageset')
        
        # 将标签页控件添加到主分割器
        self.main_splitter.addWidget(self.tab_widget)
        
        # 添加标签页切换事件处理
        self.tab_widget.currentChanged.connect(self.on_tab_changed)
    
    def create_right_panel(self):
        """创建右侧面板"""
        # 创建右侧面板容器
        right_widget = QWidget()
        right_layout = QVBoxLayout(right_widget)
        right_layout.setContentsMargins(1, 1, 1, 1)
        right_layout.addWidget(QLabel('属性编辑器:'))
        
        # 创建属性编辑器
        self.property_editor = PropertyEditor()
        self.property_editor.setMinimumWidth(250)
        
        # 将属性编辑器添加到右侧布局
        right_layout.addWidget(self.property_editor)
        
        # 将右侧面板添加到主分割器
        self.main_splitter.addWidget(right_widget)
    
    def connect_signals_slots(self):
        """连接信号与槽"""
        # 元素树项目点击
        self.element_tree.itemClicked.connect(self.on_element_clicked)
        
        # XML处理器信号
        self.xml_handler.layout_loaded.connect(self.on_layout_loaded)
        self.xml_handler.imageset_loaded.connect(self.on_imageset_loaded)
        
        # 属性编辑器信号
        self.property_editor.property_changed.connect(self.on_property_changed)
        
        # 布局转换信号
        self.design_view.layout_converted.connect(self.on_layout_converted)
        
        # 添加窗口关闭事件处理
        self.closeEvent = self.handle_close_event
        
        # 添加设计视图元素选择信号连接
        self.design_view.element_selected.connect(self.select_element)
    
    def new_layout(self):
        """新建布局文件"""
        if self.is_layout_modified:
            reply = QMessageBox.question(self, '确认', '布局已被修改，是否保存当前布局?',
                                         QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel)
            if reply == QMessageBox.Yes:
                self.save_layout()
            elif reply == QMessageBox.Cancel:
                return
        
        # 创建新的布局根元素
        from xml.etree.ElementTree import Element, SubElement
        root = Element('GUILayout')
        window = SubElement(root, 'Window')
        window.set('Type', 'DefaultWindow')
        window.set('Name', 'Root')
        
        # 添加默认属性
        prop = SubElement(window, 'Property')
        prop.set('Name', 'UnifiedAreaRect')
        prop.set('Value', '{{0.000000,0.000000},{0.000000,0.000000},{1.0,0},{1.0,0}}')
        
        # 清除当前文件路径
        self.current_layout_file = None
        
        # 使用通用的布局加载方法
        self.on_layout_loaded(root)
        
        self.statusBar().showMessage('已创建新布局')
    
    def open_layout(self):
        """打开布局文件"""
        # 获取起始目录
        start_dir = ""
        root_dir = self.config_manager.get('root_directory')
        if root_dir and os.path.exists(root_dir):
            start_dir = root_dir
        
        file_path, _ = QFileDialog.getOpenFileName(
            self,
            "打开布局文件",
            start_dir,
            "CEGUI布局文件 (*.layout);;XML文件 (*.xml);;所有文件 (*.*)"
        )
        
        if file_path:
            self.open_layout_file(file_path)
    
    def save_layout(self):
        """保存布局文件"""
        # 如果当前没有布局文件
        if not self.current_layout_file:
            # 调用另存为方法
            return self.save_layout_as()
        
        try:
            # 获取XML根元素
            root = self.design_view.get_layout_root()
            if not root:
                QMessageBox.warning(self, '警告', '没有布局可保存')
                return False
            
            # 保存布局文件
            self.xml_handler.save_layout(root, self.current_layout_file)
            
            # 更新修改状态
            self.is_layout_modified = False
            self.update_window_title()
            
            # 更新状态栏
            self.statusBar().showMessage(f'已保存布局到: {self.current_layout_file}')
            
            # 更新配置
            self.config_manager.set_last_layout_file(self.current_layout_file)
            
            # 询问是否标记为已处理
            reply = QMessageBox.question(
                self,
                '标记处理状态',
                '布局已保存，是否标记为已处理？',
                QMessageBox.Yes | QMessageBox.No
            )
            
            if reply == QMessageBox.Yes:
                self.config_manager.set_layout_processed(self.current_layout_file, True)
                # 更新布局列表中的勾选状态
                self.update_file_lists()
            
            return True
        except Exception as e:
            QMessageBox.critical(self, '错误', f'保存布局文件时出错: {e}')
            return False
    
    def save_layout_as(self):
        """另存为布局文件"""
        # 获取XML根元素
        root = self.design_view.get_layout_root()
        if not root:
            QMessageBox.warning(self, '警告', '没有布局可保存')
            return False
            
        # 获取默认目录
        default_dir = os.path.dirname(self.current_layout_file) if self.current_layout_file else self.config_manager.get('root_directory')
        
        # 显示文件保存对话框
        file_path, _ = QFileDialog.getSaveFileName(
            self,
            '保存布局文件',
            default_dir,
            'CEGUI布局文件 (*.layout);;所有文件 (*.*)'
        )
        
        if not file_path:  # 用户取消了文件对话框
            return False
            
        # 确保扩展名正确
        if not file_path.endswith('.layout'):
            file_path += '.layout'
            
        try:
            # 保存布局文件
            self.xml_handler.save_layout(root, file_path)
            
            # 更新当前文件路径
            self.current_layout_file = file_path
            
            # 更新修改状态
            self.is_layout_modified = False
            self.update_window_title()
            
            # 更新状态栏
            self.statusBar().showMessage(f'已保存布局到: {file_path}')
            
            # 更新配置
            self.config_manager.set_last_layout_file(file_path)
            
            # 询问是否标记为已处理
            reply = QMessageBox.question(
                self,
                '标记处理状态',
                '布局已保存，是否标记为已处理？',
                QMessageBox.Yes | QMessageBox.No
            )
            
            if reply == QMessageBox.Yes:
                self.config_manager.set_layout_processed(file_path, True)
                # 更新布局列表
                self.update_file_lists()
                
            return True
        except Exception as e:
            QMessageBox.critical(self, '错误', f'保存布局文件时出错: {e}')
            return False
    
    def restore_original_layout(self):
        """恢复为原始文件"""
        if not self.current_layout_file:
            QMessageBox.warning(self, '警告', '当前没有打开的布局文件')
            return
            
        # 检查备份文件是否存在
        backup_file = f"{self.current_layout_file}.init"
        if not os.path.exists(backup_file):
            QMessageBox.warning(self, '警告', f'找不到原始备份文件: {backup_file}')
            return
            
        # 确认是否恢复
        reply = QMessageBox.question(
            self, 
            '确认恢复', 
            f'确定要恢复到原始布局吗？\n当前所有修改将丢失。',
            QMessageBox.Yes | QMessageBox.No
        )
        
        if reply == QMessageBox.Yes:
            try:
                # 保存当前文件路径
                current_file = self.current_layout_file
                
                # 关闭当前文件
                self.design_view.set_layout_root(None)
                
                # 复制备份文件到原始文件
                import shutil
                shutil.copy2(backup_file, current_file)
                
                # 重新打开文件
                self.open_layout_file(current_file)
                
                self.statusBar().showMessage(f'已恢复到原始布局文件')
            except Exception as e:
                QMessageBox.critical(self, '恢复失败', f'恢复原始文件时出错: {str(e)}')
                print(f"恢复原始文件时出错: {e}")
    
    def load_imageset(self):
        """加载Imageset文件"""
        # 获取起始目录
        start_dir = ""
        imageset_dir = self.config_manager.get('imageset_search_dir')
        if imageset_dir and os.path.exists(imageset_dir):
            start_dir = imageset_dir
        else:
            root_dir = self.config_manager.get('root_directory')
            if root_dir and os.path.exists(root_dir):
                start_dir = root_dir
        
        file_path, _ = QFileDialog.getOpenFileName(
            self, 
            '加载Imageset文件', 
            start_dir, 
            'Imageset文件 (*.imageset *.xml)'
        )
        if file_path:
            imageset = self.xml_handler.load_imageset(file_path)
            if imageset:
                self.statusBar().showMessage(f'已加载Imageset文件: {file_path}')
                
                # 更新配置
                self.config_manager.set_last_imageset_file(file_path)
                
                # 如果是第一个标签页，切换到Imageset标签页
                if self.tab_widget.currentIndex() == 0:
                    self.tab_widget.setCurrentIndex(2)  # 切换到Imageset标签页
    
    def add_window(self):
        """添加窗口元素"""
        selected_item = self.element_tree.currentItem()
        if not selected_item:
            QMessageBox.warning(self, '警告', '请先选择一个父窗口元素')
            return
        
        # 获取父元素
        parent_element = selected_item.data(0, Qt.UserRole)
        
        # 创建新窗口元素
        window_type = 'OiramLook/StaticImage'  # 默认使用OiramLook/StaticImage类型
        window_name = f'Window{len(parent_element.findall("Window"))+1}'
        window_element = self.xml_handler.create_window_element(window_type, window_name)
        
        # 添加必要的属性
        # 1. UnifiedAreaRect - 位置和大小
        prop = self.xml_handler.create_property_element('UnifiedAreaRect', '{{0.1,0},{0.1,0},{0.3,0},{0.3,0}}')
        window_element.append(prop)
        
        # 2. Image - 图像路径
        prop = self.xml_handler.create_property_element('Image', 'set:biaoti30 image:LOGO')
        window_element.append(prop)
        
        # 3. UnifiedMaxSize - 最大尺寸
        prop = self.xml_handler.create_property_element('UnifiedMaxSize', '{{1.000000,0.000000},{1.000000,0.000000}}')
        window_element.append(prop)
        
        # 4. olNormalImage - OiramLook皮肤特有的正常状态图像
        prop = self.xml_handler.create_property_element('olNormalImage', 'set:biaoti30 image:LOGO')
        window_element.append(prop)
        
        # 将新窗口添加到父元素
        parent_element.append(window_element)
        
        # 标记布局为已修改
        self.is_layout_modified = True
        self.update_window_title()
        
        # 更新界面
        self.update_element_tree(self.design_view.get_layout_root())
        self.design_view.update()
        self.statusBar().showMessage(f'已添加窗口: {window_name}')
    
    def delete_window(self):
        """删除窗口元素"""
        selected_item = self.element_tree.currentItem()
        if not selected_item:
            QMessageBox.warning(self, '警告', '请先选择一个窗口元素')
            return
        
        # 获取元素
        element = selected_item.data(0, Qt.UserRole)
        
        # 确认删除
        reply = QMessageBox.question(self, '确认', f'确定删除 {element.get("Name")} 元素?',
                                     QMessageBox.Yes | QMessageBox.No)
        if reply == QMessageBox.Yes:
            # 获取父元素
            parent = self.find_parent_element(self.design_view.get_layout_root(), element)
            if parent:
                # 删除元素
                parent.remove(element)
                
                # 标记布局为已修改
                self.is_layout_modified = True
                self.update_window_title()
                
                # 更新界面
                self.update_element_tree(self.design_view.get_layout_root())
                self.design_view.update()
                self.statusBar().showMessage(f'已删除窗口: {element.get("Name")}')
    
    def find_parent_element(self, root, target):
        """查找元素的父元素"""
        for window in root.findall('.//Window'):
            for child in window.findall('Window'):
                if child == target:
                    return window
                result = self.find_parent_element(child, target)
                if result:
                    return result
        return None
    
    def on_element_clicked(self, item):
        """元素项被点击"""
        element = item.data(0, Qt.UserRole)
        if element:
            # 调用统一的元素选择方法
            self.select_element(element, update_tree=False)  # 不需要更新树，因为点击就是从树上来的
    
    def on_layout_loaded(self, root):
        """布局加载完成"""
        self.update_element_tree(root)
        self.design_view.set_layout_root(root)
        
        # 更新XML视图
        self.update_xml_view()
        
        # 重置修改状态
        self.is_layout_modified = False
        self.update_window_title()
        
        # 更新Imageset视图，显示所有加载的图集
        self.imageset_view.update_imageset_combo()
        
        # 显示加载的图集信息
        if self.xml_handler.imagesets:
            imageset_names = ", ".join(self.xml_handler.imagesets.keys())
            self.statusBar().showMessage(f'已加载布局文件和图集: {imageset_names}')
        else:
            self.statusBar().showMessage(f'已加载布局文件，未找到相关图集')
    
    def on_imageset_loaded(self, imageset):
        """Imageset加载完成"""
        self.imageset_view.update_imageset_view(imageset)
    
    def on_property_changed(self, element, name, value):
        """属性变更"""
        # 查找并更新属性
        for prop in element.findall('Property'):
            if prop.get('Name') == name:
                prop.set('Value', value)
                break
        else:
            # 如果属性不存在，则创建新属性
            prop = self.xml_handler.create_property_element(name, value)
            element.append(prop)
        
        # 标记布局为已修改
        self.is_layout_modified = True
        
        # 更新XML视图
        self.update_xml_view()
        
        # 更新窗口标题，显示修改状态
        self.update_window_title()
        
        # 更新设计视图
        self.design_view.update()
    
    def update_element_tree(self, root):
        """更新元素树"""
        # 保存当前展开状态
        expanded_items = {}
        
        def save_expanded_state(item):
            element = item.data(0, Qt.UserRole)
            if element is not None:
                element_id = id(element)
                expanded_items[element_id] = item.isExpanded()
                for i in range(item.childCount()):
                    save_expanded_state(item.child(i))
        
        # 保存所有项的展开状态
        for i in range(self.element_tree.topLevelItemCount()):
            save_expanded_state(self.element_tree.topLevelItem(i))
        
        # 清空树
        self.element_tree.clear()
        
        # 将XML树转换为树形控件项
        def add_element_to_tree(parent_item, element):
            item = QTreeWidgetItem(parent_item)
            item.setText(0, element.get('Name', '未命名'))
            item.setText(2, element.get('Type', '未知类型'))
            item.setData(0, Qt.UserRole, element)
            
            # 添加隐藏/显示图标
            visibility_button = QPushButton()
            
            # 检查元素是否被隐藏
            is_hidden = element in self.design_view.hidden_elements
            
            # 设置按钮图标和提示
            if is_hidden:
                visibility_button.setText("👁️‍🗨️")  # 隐藏状态的图标
                visibility_button.setToolTip("点击显示元素")
            else:
                visibility_button.setText("👁️")  # 显示状态的图标
                visibility_button.setToolTip("点击隐藏元素")
            
            # 设置按钮样式
            visibility_button.setStyleSheet("""
                QPushButton {
                    background-color: transparent;
                    border: none;
                    font-size: 16px;
                    padding: 2px;
                    min-width: 24px;
                    max-width: 24px;
                    min-height: 24px;
                    max-height: 24px;
                }
                QPushButton:hover {
                    background-color: rgba(100, 100, 100, 100);
                    border-radius: 12px;
                }
            """)
            
            # 存储元素引用，用于按钮点击时
            visibility_button.element = element
            
            # 连接按钮点击信号
            visibility_button.clicked.connect(lambda: self.toggle_element_visibility(visibility_button))
            
            # 将按钮设置到项目
            self.element_tree.setItemWidget(item, 1, visibility_button)
            
            # 递归添加子窗口
            for child in element.findall('Window'):
                add_element_to_tree(item, child)
            
            return item
        
        # 添加根元素
        if root.tag == 'GUILayout':
            gui_item = QTreeWidgetItem(self.element_tree)
            gui_item.setText(0, 'GUILayout')
            gui_item.setText(2, '根元素')
            gui_item.setData(0, Qt.UserRole, root)
            
            # 添加Window元素
            window = root.find('Window')
            if window is not None:
                add_element_to_tree(gui_item, window)
        else:
            add_element_to_tree(self.element_tree, root)
        
        # 恢复展开状态
        def restore_expanded_state(item):
            element = item.data(0, Qt.UserRole)
            if element is not None:
                element_id = id(element)
                if element_id in expanded_items:
                    item.setExpanded(expanded_items[element_id])
                for i in range(item.childCount()):
                    restore_expanded_state(item.child(i))
        
        # 默认展开第一级
        for i in range(self.element_tree.topLevelItemCount()):
            top_item = self.element_tree.topLevelItem(i)
            top_item.setExpanded(True)
            for j in range(top_item.childCount()):
                restore_expanded_state(top_item.child(j))
    
    def show_about(self):
        """显示关于对话框"""
        QMessageBox.about(self, '关于CEGUI布局编辑器',
                          'CEGUI布局编辑器 v1.0\n\n'
                          '一个用于编辑CEGUI 0.4布局文件的可视化编辑器\n\n'
                          '支持.imageset和.layout文件的编辑')
    
    def set_preview_resolution(self, width, height):
        """设置预览分辨率"""
        # 调用原有的设置预览分辨率方法
        if hasattr(self, 'design_view'):
            self.design_view.set_resolution(width, height)
            
            # 更新配置
            self.config_manager.set_preview_resolution(width, height)
            
            # 更新下拉框选择
            resolution_text = f"{width}x{height}"
            index = self.resolution_combo.findText(resolution_text)
            if index >= 0:
                self.resolution_combo.setCurrentIndex(index)
            
            self.statusBar().showMessage(f'预览分辨率已设置为 {width}x{height}')
    
    def on_resolution_changed(self, resolution_text):
        """分辨率下拉框改变事件"""
        try:
            width, height = map(int, resolution_text.split('x'))
            self.set_preview_resolution(width, height)
            
            # 更新菜单选中状态
            for action in self.resolution_action_group.actions():
                if action.text() == resolution_text:
                    action.setChecked(True)
                    break
        except Exception as e:
            print(f"解析分辨率出错: {e}")
    
    def toggle_final_render_mode(self, enabled):
        """切换最终渲染模式"""
        # 同步菜单和工具栏状态
        self.final_render_mode_action.setChecked(enabled)
        self.final_render_checkbox.setChecked(enabled)
        
        # 设置画布渲染模式
        self.design_view.set_final_render_mode(enabled)
            
        mode_text = "最终渲染模式" if enabled else "编辑模式"
        self.statusBar().showMessage(f'已切换到{mode_text}')
        
        # 更新视图
        if hasattr(self, 'tab_widget'):
            if self.tab_widget.currentIndex() == 1:  # XML视图
                self.update_xml_view()
    
    def toggle_click_select_only(self, enabled):
        """切换只通过点击选择元素模式"""
        # 设置设计视图的选择模式
        if hasattr(self, 'design_view'):
            self.design_view.set_click_select_only(enabled)
            
        # 显示状态消息
        mode_text = "启用" if enabled else "禁用"
        self.statusBar().showMessage(f'已{mode_text}只通过点击选择元素模式')
    
    def set_imageset_search_dir(self):
        """设置Imageset搜索目录"""
        # 获取起始目录
        start_dir = self.config_manager.get('imageset_search_dir', '')
        if not start_dir:
            start_dir = self.config_manager.get('root_directory', '')
        
        dir_path = QFileDialog.getExistingDirectory(
            self,
            "选择Imageset搜索目录",
            start_dir,
            QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks
        )
        
        if dir_path:
            # 设置为XML处理器的Imageset搜索目录
            if self.xml_handler.set_imageset_search_dir(dir_path):
                self.statusBar().showMessage(f'已设置Imageset搜索目录: {dir_path}')
                
                # 保存配置
                self.config_manager.set_imageset_search_dir(dir_path)
                
                # 自动搜索新目录中的imageset文件并加载
                found_imagesets = []
                
                # 搜索所有.imageset文件
                for file_path in glob.glob(os.path.join(dir_path, "*.imageset")):
                    basename = os.path.basename(file_path)
                    imageset_name = os.path.splitext(basename)[0]
                    found_imagesets.append(basename)
                
                if found_imagesets:
                    # 显示找到的imageset文件
                    message = f'在 {dir_path} 中找到 {len(found_imagesets)} 个imageset文件:\n'
                    message += ', '.join(found_imagesets[:10])
                    if len(found_imagesets) > 10:
                        message += f' 等{len(found_imagesets)}个文件'
                    
                    QMessageBox.information(
                        self,
                        "找到Imageset文件",
                        message
                    )
                    
                    # 提示用户是否加载布局文件中引用的imageset
                    if self.current_layout_file:
                        root = self.design_view.get_layout_root()
                        if root:
                            reply = QMessageBox.question(
                                self,
                                "重新加载图集",
                                "是否重新加载当前布局文件中引用的图集？\n这将检查新设置的搜索目录中的文件。",
                                QMessageBox.Yes | QMessageBox.No
                            )
                            
                            if reply == QMessageBox.Yes:
                                # 重新自动加载布局中引用的图集
                                self.xml_handler.auto_load_imagesets(root, os.path.dirname(self.current_layout_file))
                                
                                # 更新Imageset视图
                                self.imageset_view.update_imageset_combo()
            else:
                QMessageBox.warning(
                    self,
                    "目录设置失败",
                    f"无法设置目录 {dir_path} 为Imageset搜索目录。\n目录可能不存在或已经在搜索列表中。"
                )
    
    def set_root_directory(self):
        """设置工程根目录"""
        # 获取起始目录
        start_dir = self.config_manager.get('root_directory', '')
        
        dir_path = QFileDialog.getExistingDirectory(
            self,
            "选择工程根目录",
            start_dir,
            QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks
        )
        
        if dir_path:
            # 设置为XML处理器的根目录
            if self.xml_handler.set_root_directory(dir_path):
                self.statusBar().showMessage(f'已设置工程根目录: {dir_path}')
                
                # 保存配置
                self.config_manager.set_root_directory(dir_path)
                
                # 创建布局文件和图集文件列表的UI
                self.create_file_lists_panel()
                
                # 如果当前已有加载的布局文件，询问是否重新加载布局中引用的图集
                if self.current_layout_file:
                    root = self.design_view.get_layout_root()
                    if root:
                        reply = QMessageBox.question(
                            self,
                            "重新加载图集",
                            "是否重新加载当前布局文件中引用的图集？\n这将检查新设置的根目录中的图集文件。",
                            QMessageBox.Yes | QMessageBox.No
                        )
                        
                        if reply == QMessageBox.Yes:
                            # 重新自动加载布局中引用的图集
                            self.xml_handler.auto_load_imagesets(root, os.path.dirname(self.current_layout_file))
                            
                            # 更新Imageset视图
                            self.imageset_view.update_imageset_combo()
            else:
                QMessageBox.warning(
                    self,
                    "目录设置失败",
                    f"无法设置目录 {dir_path} 为工程根目录。\n目录可能不存在。"
                )
    
    def create_file_lists_panel(self):
        """创建布局文件和图集文件列表面板"""
        # 检查是否已经创建过
        if hasattr(self, 'file_lists_dock'):
            # 如果已经创建，只更新列表内容
            self.update_file_lists()
            return
        
        # 创建停靠窗口
        self.file_lists_dock = QDockWidget("文件列表", self)
        self.file_lists_dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
        
        # 创建主容器
        container = QWidget()
        layout = QVBoxLayout(container)
        
        # 创建标签页控件
        file_lists_tab = QTabWidget()
        
        # 创建布局文件列表
        self.layouts_list = QTreeWidget()
        self.layouts_list.setHeaderLabels(["已处理", "布局文件", "路径"])
        self.layouts_list.itemDoubleClicked.connect(self.on_layout_item_double_clicked)
        
        # 创建图集文件列表
        self.imagesets_list = QTreeWidget()
        self.imagesets_list.setHeaderLabels(["图集名称", "文件名", "路径"])
        self.imagesets_list.itemDoubleClicked.connect(self.on_imageset_item_double_clicked)
        
        # 添加到标签页
        file_lists_tab.addTab(self.layouts_list, "布局文件")
        file_lists_tab.addTab(self.imagesets_list, "图集文件")
        
        layout.addWidget(file_lists_tab)
        
        # 添加预加载按钮
        preload_button = QPushButton("预加载所有图集")
        preload_button.clicked.connect(self.preload_all_imagesets)
        layout.addWidget(preload_button)
        
        # 设置内容
        self.file_lists_dock.setWidget(container)
        
        # 添加到主窗口
        self.addDockWidget(Qt.LeftDockWidgetArea, self.file_lists_dock)
        
        # 更新列表内容
        self.update_file_lists()
        
        # 连接信号
        self.xml_handler.layouts_directory_scanned.connect(self.update_layouts_list)
        self.xml_handler.imagesets_directory_scanned.connect(self.update_imagesets_list)
    
    def update_file_lists(self):
        """更新文件列表"""
        # 清空列表
        self.layouts_list.clear()
        self.imagesets_list.clear()
        
        # 更新布局文件列表
        self.update_layouts_list(self.xml_handler.layout_files)
        
        # 更新图集文件列表
        self.update_imagesets_list(self.xml_handler.imageset_files)
    
    def update_layouts_list(self, layout_files):
        """更新布局文件列表"""
        self.layouts_list.clear()
        
        # 修改表头，添加"已处理"列
        self.layouts_list.setHeaderLabels(["已处理", "布局文件", "路径"])
        
        for layout_info in layout_files:
            item = QTreeWidgetItem(self.layouts_list)
            
            # 添加勾选框
            item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
            
            # 设置勾选状态
            file_path = layout_info['path']
            is_processed = self.config_manager.is_layout_processed(file_path)
            item.setCheckState(0, Qt.Checked if is_processed else Qt.Unchecked)
            
            # 设置文件名和路径
            item.setText(1, layout_info['name'])
            item.setText(2, layout_info['rel_path'])
            item.setData(0, Qt.UserRole, layout_info)  # 存储完整信息
        
        # 调整列宽
        self.layouts_list.resizeColumnToContents(0)
        self.layouts_list.resizeColumnToContents(1)
        self.layouts_list.resizeColumnToContents(2)
        
        # 连接勾选状态变化的信号
        if not hasattr(self, 'layouts_list_connected'):
            self.layouts_list.itemChanged.connect(self.on_layout_processed_changed)
            self.layouts_list_connected = True
    
    def update_imagesets_list(self, imageset_files):
        """更新图集文件列表"""
        self.imagesets_list.clear()
        
        for imageset_info in imageset_files:
            item = QTreeWidgetItem(self.imagesets_list)
            item.setText(0, imageset_info['name'])
            item.setText(1, imageset_info['file_name'])
            item.setText(2, imageset_info['rel_path'])
            item.setData(0, Qt.UserRole, imageset_info)  # 存储完整信息
        
        # 调整列宽
        self.imagesets_list.resizeColumnToContents(0)
        self.imagesets_list.resizeColumnToContents(1)
        self.imagesets_list.resizeColumnToContents(2)
    
    def on_layout_item_double_clicked(self, item, column):
        """布局文件项被双击"""
        # 忽略第一列（勾选框）的双击
        if column == 0:
            return
            
        layout_info = item.data(0, Qt.UserRole)
        if layout_info:
            # 加载选中的布局文件
            file_path = layout_info['path']
            self.open_layout_file(file_path)
    
    def on_imageset_item_double_clicked(self, item, column):
        """图集文件项被双击"""
        imageset_info = item.data(0, Qt.UserRole)
        if imageset_info:
            # 加载选中的图集文件
            file_path = imageset_info['path']
            imageset = self.xml_handler.load_imageset(file_path)
            if imageset:
                self.statusBar().showMessage(f'已加载图集文件: {file_path}')
                # 切换到Imageset标签页
                self.tab_widget.setCurrentIndex(2)  # Imageset标签页索引
                # 更新Imageset视图
                self.imageset_view.update_imageset_view(imageset)
                
                # 更新配置
                self.config_manager.set_last_imageset_file(file_path)
    
    def preload_all_imagesets(self):
        """预加载所有图集文件"""
        count = self.xml_handler.preload_all_imagesets()
        QMessageBox.information(
            self,
            "预加载完成",
            f"已成功加载 {count} 个图集文件。"
        )
        # 更新Imageset视图
        self.imageset_view.update_imageset_combo()
    
    def on_element_clicked(self, item):
        """元素项被点击"""
        element = item.data(0, Qt.UserRole)
        if element:
            # 调用统一的元素选择方法
            self.select_element(element, update_tree=False)  # 不需要更新树，因为点击就是从树上来的
    
    def handle_close_event(self, event):
        """处理窗口关闭事件"""
        # 如果布局已修改，询问是否保存
        if self.is_layout_modified:
            reply = QMessageBox.question(self, '确认', '布局已被修改，是否保存?',
                                       QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel)
            if reply == QMessageBox.Yes:
                if not self.save_layout():
                    event.ignore()
                    return
            elif reply == QMessageBox.Cancel:
                event.ignore()
                return
        
        # 保存配置
        self.save_config()
        event.accept()
    
    def update_window_title(self):
        """更新窗口标题，显示当前文件和修改状态"""
        title = 'CEGUI布局编辑器'
        if self.current_layout_file:
            basename = os.path.basename(self.current_layout_file)
            title = f"{basename} - {title}"
            if self.is_layout_modified:
                title = f"*{title}"
        self.setWindowTitle(title)
    
    def convert_to_1080p(self):
        """将布局从800x600转换为1920x1080"""
        if not self.design_view.get_layout_root():
            QMessageBox.warning(self, '警告', '请先加载一个布局文件')
            return
        
        # 确认转换
        reply = QMessageBox.question(self, '确认', '确定将当前布局从800x600转换为1920x1080分辨率？\n此操作将修改所有元素的位置和大小。',
                                 QMessageBox.Yes | QMessageBox.No)
        if reply == QMessageBox.Yes:
            # 执行转换
            result = self.design_view.convert_layout_to_1080p()
            if result:
                # 设置预览分辨率为1920x1080
                self.set_preview_resolution(1920, 1080)
            else:
                QMessageBox.warning(self, '错误', '转换失败，请确保已加载布局文件')
    
    def on_layout_converted(self):
        """布局转换完成处理"""
        self.statusBar().showMessage('布局已成功转换为1920x1080分辨率')
        
        # 更新为已修改状态
        self.is_layout_modified = True
        self.update_window_title()
    
    def toggle_element_visibility(self, button):
        """切换元素的可见性
        
        参数:
            button: 被点击的按钮
        """
        # 获取按钮关联的元素
        element = button.element
        
        # 调用设计视图的方法切换元素可见性
        new_hidden = self.design_view.toggle_element_visibility(element)
        
        # 更新按钮的文本和提示
        if new_hidden:
            button.setText("👁️‍🗨️")  # 隐藏状态的图标
            button.setToolTip("点击显示元素")
        else:
            button.setText("👁️")  # 显示状态的图标
            button.setToolTip("点击隐藏元素")
        
        # 更新状态栏信息
        element_name = element.get('Name', '未命名')
        status = "隐藏" if new_hidden else "显示"
        self.statusBar().showMessage(f"元素 '{element_name}' 已{status}")
        
        # 更新设计视图画布
        self.design_view.update()

    def show_element_tree_menu(self, position):
        """显示元素树的右键菜单"""
        menu = QMenu()
        
        # 获取当前选中的项
        item = self.element_tree.itemAt(position)
        if item:
            element = item.data(0, Qt.UserRole)
            if element:
                # 添加查看XML菜单项
                view_xml_action = menu.addAction('查看XML')
                view_xml_action.triggered.connect(lambda: self.show_element_xml(element))
                
                # 添加坐标转换菜单
                coords_menu = QMenu('坐标转换', menu)
                
                # 添加坐标转换选项
                show_coords_action = coords_menu.addAction('查看坐标信息')
                show_coords_action.triggered.connect(lambda: self.show_element_coordinates(element))
                
                coords_menu.addSeparator()
                
                abs_to_rel_action = coords_menu.addAction('复制为相对坐标')
                abs_to_rel_action.triggered.connect(lambda: self.copy_relative_coordinates(element))
                
                rel_to_abs_action = coords_menu.addAction('复制为绝对坐标')
                rel_to_abs_action.triggered.connect(lambda: self.copy_absolute_coordinates(element))
                
                # 添加直接转换坐标的选项
                coords_menu.addSeparator()
                convert_to_abs_action = coords_menu.addAction('转换为绝对坐标')
                convert_to_abs_action.triggered.connect(lambda: self.convert_to_absolute_coordinates(element))
                
                convert_to_rel_action = coords_menu.addAction('还原为相对坐标')
                convert_to_rel_action.triggered.connect(lambda: self.convert_to_relative_coordinates(element))
                
                # 将坐标转换菜单添加到主菜单
                menu.addMenu(coords_menu)
                
                # 添加缩放菜单
                scale_menu = QMenu('缩放选项', menu)
                
                # 只缩放当前元素
                scale_to_fullscreen_action = scale_menu.addAction('缩放元素到全屏')
                scale_to_fullscreen_action.triggered.connect(lambda: self.scale_element_to_fullscreen(element, False))
                
                # 智能平铺缩放
                scale_recursive_action = scale_menu.addAction('智能平铺子元素到全屏')
                scale_recursive_action.triggered.connect(lambda: self.arrange_child_elements(element))
                
                # 保持嵌套结构缩放
                keep_nested_structure_action = scale_menu.addAction('保持嵌套结构缩放到全屏')
                keep_nested_structure_action.triggered.connect(lambda: self.scale_element_to_fullscreen(element, True))
                
                # 恢复原始比例
                restore_original_action = scale_menu.addAction('恢复原始比例')
                restore_original_action.triggered.connect(lambda: self.restore_original_proportions(element))
                
                # 添加调整宽高比选项（带快捷键提示）
                adjust_ratio_action = scale_menu.addAction('宽度调整为4分之3 (S)')
                adjust_ratio_action.triggered.connect(lambda: self.adjust_aspect_ratio(element))
                
                # 将缩放菜单添加到主菜单
                menu.addMenu(scale_menu)
                
                menu.addSeparator()
                
                # 添加删除元素菜单项
                delete_action = menu.addAction('删除元素')
                delete_action.triggered.connect(lambda: self.delete_element(element))
                
                # 添加隐藏/显示菜单项
                if element in self.design_view.hidden_elements:
                    show_action = menu.addAction('显示元素')
                    show_action.triggered.connect(lambda: self._toggle_element_visibility_from_menu(element, False))
                else:
                    hide_action = menu.addAction('隐藏元素')
                    hide_action.triggered.connect(lambda: self._toggle_element_visibility_from_menu(element, True))
        
        # 显示菜单
        menu.exec_(self.element_tree.viewport().mapToGlobal(position))
    
    def _toggle_element_visibility_from_menu(self, element, hide):
        """从菜单切换元素可见性
        
        参数:
            element: 要切换可见性的元素
            hide: 是否隐藏元素
        """
        # 设置元素隐藏状态
        new_hidden = self.design_view.set_element_hidden(element, hide)
        
        # 查找元素对应的树项
        def find_tree_item_for_element(element):
            for i in range(self.element_tree.topLevelItemCount()):
                root_item = self.element_tree.topLevelItem(i)
                found = self._find_item_for_element_recursive(root_item, element)
                if found:
                    return found
            return None
        
        # 查找并更新按钮状态
        item = find_tree_item_for_element(element)
        if item:
            button = self.element_tree.itemWidget(item, 1)
            if button:
                if new_hidden:
                    button.setText("👁️‍🗨️")  # 隐藏状态的图标
                    button.setToolTip("点击显示元素")
                else:
                    button.setText("👁️")  # 显示状态的图标
                    button.setToolTip("点击隐藏元素")
        
        # 更新状态栏信息
        element_name = element.get('Name', '未命名')
        status = "隐藏" if new_hidden else "显示"
        self.statusBar().showMessage(f"元素 '{element_name}' 已{status}")
        
        # 更新设计视图
        self.design_view.update()
    
    def _find_item_for_element_recursive(self, item, target_element):
        """递归查找元素对应的树项
        
        参数:
            item: 当前树项
            target_element: 目标元素
            
        返回:
            找到的树项或None
        """
        # 检查当前项
        if item.data(0, Qt.UserRole) == target_element:
            return item
            
        # 递归检查子项
        for i in range(item.childCount()):
            child_item = item.child(i)
            found = self._find_item_for_element_recursive(child_item, target_element)
            if found:
                return found
                
        return None
    
    def show_element_xml(self, element):
        """显示元素的XML内容"""
        if not element:
            return
        
        # 创建XML内容窗口
        if not self.xml_view_dialog:
            self.xml_view_dialog = QDialog(self)
            self.xml_view_dialog.setWindowTitle('XML查看器')
            self.xml_view_dialog.setMinimumSize(600, 400)
            
            # 创建布局
            layout = QVBoxLayout(self.xml_view_dialog)
            
            # 创建XML文本编辑器
            self.xml_text_edit = QTextEdit()
            self.xml_text_edit.setReadOnly(True)  # 只读模式
            self.xml_text_edit.setLineWrapMode(QTextEdit.NoWrap)  # 不自动换行
            self.xml_text_edit.setFont(QFont("Courier New", 10))  # 使用等宽字体
            
            # 添加XML文本编辑器到布局
            layout.addWidget(self.xml_text_edit)
            
            # 创建按钮
            button_layout = QHBoxLayout()
            
            # 创建关闭按钮
            close_button = QPushButton('关闭')
            close_button.clicked.connect(self.xml_view_dialog.close)
            button_layout.addWidget(close_button)
            
            # 创建复制按钮
            copy_button = QPushButton('复制到剪贴板')
            copy_button.clicked.connect(lambda: QApplication.clipboard().setText(self.xml_text_edit.toPlainText()))
            button_layout.addWidget(copy_button)
            
            # 添加按钮布局到主布局
            layout.addLayout(button_layout)
        
        # 将元素转换为XML字符串
        xml_string = self.element_to_xml_string(element)
        
        # 更新文本编辑器内容
        self.xml_text_edit.setText(xml_string)
        
        # 显示对话框
        self.xml_view_dialog.show()
    
    def element_to_xml_string(self, element):
        """将元素转换为XML字符串
        
        参数:
            element: 要转换的XML元素
            
        返回:
            str: 格式化的XML字符串
        """
        if element is None:
            return "错误: 元素为空"
            
        # 检查元素类型
        if not isinstance(element, ET.Element):
            return f"错误: 不是有效的XML元素 (类型: {type(element)})"
            
        try:
            # 创建临时的ElementTree
            rough_string = ET.tostring(element, 'utf-8')
            
            # 使用minidom格式化XML
            reparsed = minidom.parseString(rough_string)
            pretty_string = reparsed.toprettyxml(indent="  ")
            return pretty_string
        except Exception as e:
            print(f"XML格式化失败: {e}")
            import traceback
            traceback.print_exc()
            # 如果格式化失败，返回原始字符串
            try:
                return rough_string.decode('utf-8')
            except:
                return f"XML转换错误: {str(e)}"

    def delete_element(self, element):
        """删除元素"""
        if not element or not self.design_view.get_layout_root():
            return
            
        # 不允许删除根元素
        if element == self.design_view.get_layout_root():
            QMessageBox.warning(self, '警告', '不能删除根元素')
            return
            
        # 查找父元素
        parent_element = self.design_view.utils.find_parent_element(element)
        if not parent_element:
            QMessageBox.warning(self, '警告', '无法找到父元素')
            return
            
        # 删除元素
        try:
            # 确认删除
            element_name = element.get('Name', '未命名')
            reply = QMessageBox.question(self, '确认删除', 
                                     f'确定要删除元素 "{element_name}" 吗?',
                                     QMessageBox.Yes | QMessageBox.No)
            if reply == QMessageBox.Yes:
                parent_element.remove(element)
                
                # 更新元素树
                self.update_element_tree(self.design_view.get_layout_root())
                
                # 更新设计视图
                self.design_view.set_selected_element(None)
                self.design_view.update()
                
                # 更新XML视图
                self.update_xml_view()
                
                # 更新属性编辑器
                self.property_editor.set_element(None)
                
                # 标记布局已修改
                self.is_layout_modified = True
                self.update_window_title()
                
                self.statusBar().showMessage(f'已删除元素: {element_name}')
        except Exception as e:
            QMessageBox.critical(self, '错误', f'删除元素时出错: {str(e)}')

    def on_tab_changed(self, index):
        """处理标签页切换事件"""
        # 如果切换到XML标签页（索引为1），则更新XML内容
        if index == 1:
            self.update_xml_view()

    def update_xml_view(self):
        """更新XML视图的内容，显示格式化的XML
        
        注意：这只会更新XML视图内容，不会改变布局根元素
        """
        root = self.design_view.get_layout_root()
        if root:
            try:
                # 创建临时的ElementTree
                rough_string = ET.tostring(root, 'utf-8')
                
                # 使用minidom格式化XML
                reparsed = minidom.parseString(rough_string)
                pretty_string = reparsed.toprettyxml(indent="  ")
                
                # 更新文本编辑器内容（仅显示，不修改原始数据）
                self.xml_text_editor.setText(pretty_string)
            except Exception as e:
                error_message = f"XML格式化错误: {str(e)}"
                print(error_message)
                self.xml_text_editor.setText(error_message)
        else:
            self.xml_text_editor.setText("未加载布局文件")

    def create_recent_files_menu(self):
        """创建最近打开文件菜单"""
        self.recent_menu.clear()
        recent_layouts = self.config_manager.get('recent_layouts', [])
        
        if not recent_layouts:
            no_recent_action = QAction('没有最近文件', self)
            no_recent_action.setEnabled(False)
            self.recent_menu.addAction(no_recent_action)
            return
        
        for file_path in recent_layouts:
            if os.path.exists(file_path):
                action = QAction(file_path, self)
                action.triggered.connect(lambda checked, path=file_path: self.open_recent_layout(path))
                self.recent_menu.addAction(action)
    
    def load_config(self):
        """加载配置"""
        # 设置窗口几何信息
        geom = self.config_manager.get('window_geometry')
        if geom:
            self.setGeometry(geom['x'], geom['y'], geom['width'], geom['height'])
        
        # 设置工程根目录
        root_dir = self.config_manager.get('root_directory')
        if root_dir and os.path.exists(root_dir):
            self.xml_handler.set_root_directory(root_dir)
            self.create_file_lists_panel()
        
        # 设置Imageset搜索目录
        imageset_dir = self.config_manager.get('imageset_search_dir')
        if imageset_dir and os.path.exists(imageset_dir):
            self.xml_handler.set_imageset_search_dir(imageset_dir)
        
        # 设置预览分辨率
        preview_res = self.config_manager.get('preview_resolution')
        if preview_res:
            self.set_preview_resolution(preview_res['width'], preview_res['height'])
        
        # 创建"最近打开"菜单
        self.create_recent_files_menu()
        
        # 加载上次打开的布局文件
        last_layout = self.config_manager.get('last_layout_file')
        if last_layout and os.path.exists(last_layout):
            self.open_layout_file(last_layout)
            
        # 加载上次打开的Imageset文件
        last_imageset = self.config_manager.get('last_imageset_file')
        if last_imageset and os.path.exists(last_imageset):
            # 在异步队列中加载，避免与布局文件加载冲突
            QTimer.singleShot(100, lambda: self.load_last_imageset(last_imageset))
    
    def load_last_imageset(self, file_path):
        """加载上次使用的Imageset文件"""
        imageset = self.xml_handler.load_imageset(file_path)
        if imageset:
            self.statusBar().showMessage(f'已加载Imageset文件: {file_path}')
            # 切换到Imageset标签页
            self.tab_widget.setCurrentIndex(2)  # Imageset标签页索引
            # 更新Imageset视图
            self.imageset_view.update_imageset_view(imageset)
    
    def save_config(self):
        """保存配置"""
        # 保存窗口几何信息
        geo = self.geometry()
        self.config_manager.set_window_geometry(geo.x(), geo.y(), geo.width(), geo.height())
        
        # 保存当前布局文件
        if self.current_layout_file:
            self.config_manager.set_last_layout_file(self.current_layout_file)
    
    def open_recent_layout(self, file_path):
        """打开最近的布局文件"""
        if not os.path.exists(file_path):
            QMessageBox.warning(self, '文件不存在', f'文件 {file_path} 不存在或已被删除')
            # 从最近文件列表中移除
            recent_layouts = self.config_manager.get('recent_layouts', [])
            if file_path in recent_layouts:
                recent_layouts.remove(file_path)
                self.config_manager.set('recent_layouts', recent_layouts)
                self.config_manager.save_config()
                self.create_recent_files_menu()
            return
        
        self.open_layout_file(file_path)
    
    def open_layout_file(self, file_path):
        """打开指定的布局文件"""
        # 如果当前已有布局文件并且已被修改，询问是否保存
        if self.current_layout_file and self.is_layout_modified:
            reply = QMessageBox.question(self, '确认', '布局已被修改，是否保存当前布局?',
                                       QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel)
            if reply == QMessageBox.Yes:
                self.save_layout()
            elif reply == QMessageBox.Cancel:
                return
        
        # 加载布局文件
        root = self.xml_handler.load_layout(file_path)
        if root:
            self.current_layout_file = file_path
            self.is_layout_modified = False
            self.statusBar().showMessage(f'已加载布局文件: {file_path}')
            
            # 更新元素树
            self.update_element_tree(root)
            
            # 更新设计视图
            self.design_view.set_layout_root(root)
            self.design_view.update()
            
            # 更新XML视图
            self.update_xml_view()
            
            # 检查是否需要创建备份文件
            backup_file = f"{file_path}.init"
            if not os.path.exists(backup_file) and os.path.exists(file_path):
                try:
                    # 创建备份文件
                    import shutil
                    shutil.copy2(file_path, backup_file)
                    print(f"已创建初始备份文件: {backup_file}")
                except Exception as e:
                    print(f"创建初始备份文件时出错: {e}")
            
            # 更新配置
            self.config_manager.set_last_layout_file(file_path)
            
            # 更新窗口标题
            self.update_window_title()
            
            # 更新"最近打开"菜单
            self.create_recent_files_menu()
            
            # 在文件列表中高亮显示当前文件
            self.update_selected_file_in_list()
    
    def closeEvent(self, event):
        """重写关闭事件"""
        self.handle_close_event(event)

    def scale_element_to_fullscreen(self, element, recursive):
        """缩放元素及其子元素到全屏
        
        参数:
            element: 要缩放的元素
            recursive: 是否递归处理子元素
        """
        if not element:
            print("错误: 缩放到全屏的元素为空")
            return
            
        # 获取当前预览分辨率和元素名称
        width, height = self.design_view.get_resolution()
        element_name = element.get('Name', '未命名')
        print(f"缩放元素 '{element_name}' 到全屏，递归模式: {recursive}")
        
        try:
            # 获取父元素矩形区域
            parent_element = self.design_view.utils.find_parent_element(element)
            if parent_element:
                parent_rect = self.design_view.utils.parse_area_rect(parent_element, QRect(0, 0, width, height))
            else:
                parent_rect = QRect(0, 0, width, height)
                
            # 获取当前元素的原始矩形区域
            original_rect = self.design_view.utils.parse_area_rect(element, parent_rect)
            if not original_rect:
                print(f"无法获取元素 '{element_name}' 的区域")
                return
                
            print(f"原始区域: ({original_rect.x()}, {original_rect.y()}, {original_rect.width()}, {original_rect.height()})")
            
            # 使用工具类的更新位置函数 - 这个函数会自动更新子元素
            # 设置为全屏区域
            new_x, new_y = 0, 0
            new_width, new_height = parent_rect.width(), parent_rect.height()
            print(f"新区域: ({new_x}, {new_y}, {new_width}, {new_height})")
            
            # 调用优化后的元素位置更新函数 - 这个函数会处理子元素
            if recursive:
                # 如果需要递归处理，使用update_element_position_optimized
                # 这个函数会自动更新所有子元素，保持原有的相对位置关系
                self.design_view.utils.update_element_position_optimized(
                    element, parent_rect, new_x, new_y, new_width, new_height
                )
                print(f"元素 '{element_name}' 及其子元素已递归缩放到全屏")
            else:
                # 不处理子元素，只更新当前元素的位置
                # 计算相对坐标并直接设置UnifiedAreaRect属性
                if parent_rect.width() > 0 and parent_rect.height() > 0:
                    x1_rel = (new_x - parent_rect.x()) / parent_rect.width()
                    y1_rel = (new_y - parent_rect.y()) / parent_rect.height()
                    x2_rel = (new_x + new_width - parent_rect.x()) / parent_rect.width()
                    y2_rel = (new_y + new_height - parent_rect.y()) / parent_rect.height()
                    
                    # 格式化新的UnifiedAreaRect值
                    new_value = f"{{{{{x1_rel:.6f},0}},{{{y1_rel:.6f},0}},{{{x2_rel:.6f},0}},{{{y2_rel:.6f},0}}}}"
                    
                    # 更新元素的UnifiedAreaRect属性
                    for prop in element.findall('Property'):
                        if prop.get('Name') == 'UnifiedAreaRect':
                            prop.set('Value', new_value)
                            print(f"已设置元素 '{element_name}' 的区域为: {new_value}")
                            break
                    else:
                        # 如果没有找到UnifiedAreaRect属性，添加一个
                        prop = ET.SubElement(element, 'Property')
                        prop.set('Name', 'UnifiedAreaRect')
                        prop.set('Value', new_value)
                        print(f"添加元素 '{element_name}' 的区域: {new_value}")
                print(f"元素 '{element_name}' 已缩放到全屏")
                
            # 标记布局为已修改
            self.is_layout_modified = True
            self.update_window_title()
            
            # 更新设计视图
            self.design_view.update()
            
            # 更新属性编辑器（如果当前选中的就是这个元素）
            if self.property_editor.current_element == element:
                self.property_editor.update_properties()
                
            # 更新XML视图
            self.update_xml_view()
            
            # 提示用户
            if recursive:
                message = f'元素 "{element_name}" 及其子元素已递归缩放到全屏，保持原有结构'
            else:
                message = f'元素 "{element_name}" 已缩放到全屏'
                
            self.statusBar().showMessage(message)
            
        except Exception as e:
            print(f"缩放元素时出错: {e}")
            import traceback
            traceback.print_exc()
            QMessageBox.warning(self, '错误', f'缩放元素时出错: {str(e)}')

    def arrange_child_elements(self, parent_element):
        """智能平铺子元素到全屏
        
        参数:
            parent_element: 父元素
        """
        if not parent_element:
            return
            
        # 首先将父元素缩放到全屏
        self.set_element_area_rect(parent_element, "{{0,0},{0,0},{1,0},{1,0}}")
            
        # 获取子元素
        children = parent_element.findall('Window')
        if not children:
            return
            
        # 根据子元素数量决定布局方式
        count = len(children)
        
        if count == 1:
            # 单个子元素，使用整个空间（但留有少量边距）
            self.set_element_area_rect(children[0], "{{0.05,0},{0.05,0},{0.95,0},{0.95,0}}")
        elif count == 2:
            # 两个子元素，水平排列
            self.set_element_area_rect(children[0], "{{0.02,0},{0.02,0},{0.48,0},{0.98,0}}")
            self.set_element_area_rect(children[1], "{{0.52,0},{0.02,0},{0.98,0},{0.98,0}}")
        elif count == 3:
            # 三个子元素，一个在上，两个在下水平排列
            self.set_element_area_rect(children[0], "{{0.02,0},{0.02,0},{0.98,0},{0.48,0}}")
            self.set_element_area_rect(children[1], "{{0.02,0},{0.52,0},{0.48,0},{0.98,0}}")
            self.set_element_area_rect(children[2], "{{0.52,0},{0.52,0},{0.98,0},{0.98,0}}")
        elif count == 4:
            # 四个子元素，田字布局
            self.set_element_area_rect(children[0], "{{0.02,0},{0.02,0},{0.48,0},{0.48,0}}")
            self.set_element_area_rect(children[1], "{{0.52,0},{0.02,0},{0.98,0},{0.48,0}}")
            self.set_element_area_rect(children[2], "{{0.02,0},{0.52,0},{0.48,0},{0.98,0}}")
            self.set_element_area_rect(children[3], "{{0.52,0},{0.52,0},{0.98,0},{0.98,0}}")
        else:
            # 更多子元素，采用网格布局
            # 计算每个元素应占的行和列
            cols = max(2, min(int(count**0.5) + (1 if count**0.5 != int(count**0.5) else 0), 5))
            rows = (count + cols - 1) // cols  # 向上取整
            
            # 计算每个格子的宽度和高度
            cell_width = (0.96) / cols
            cell_height = (0.96) / rows
            margin = 0.02
            
            # 为每个子元素设置位置
            for i, child in enumerate(children):
                row = i // cols
                col = i % cols
                
                # 计算格子的边界
                left = margin + col * cell_width
                top = margin + row * cell_height
                right = left + cell_width - margin
                bottom = top + cell_height - margin
                
                # 设置元素位置
                area_rect = f"{{{{{left},0}},{{{top},0}},{{{right},0}},{{{bottom},0}}}}"
                self.set_element_area_rect(child, area_rect)
        
        # 标记布局为已修改
        self.is_layout_modified = True
        self.update_window_title()
        
        # 更新设计视图
        self.design_view.update()
        
        # 更新XML视图
        self.update_xml_view()
        
        # 提示用户
        element_name = parent_element.get('Name', '未命名')
        self.statusBar().showMessage(f'元素 "{element_name}" 的子元素已智能平铺')

    def restore_original_proportions(self, element):
        """恢复元素到原始比例，并按此比例调整子元素
        保持宽边或长边与调整前相同，只调整比例
        
        参数:
            element: 要恢复的元素
        """
        if not element:
            print("错误: 恢复原始比例的元素为空")
            return
            
        # 获取元素名称用于日志
        element_name = element.get('Name', '未命名')
        print(f"恢复元素 '{element_name}' 到原始比例")
        
        try:
            # 查找元素在图集中的原始尺寸
            original_size = self.find_element_original_size(element)
            if not original_size:
                print(f"无法找到元素 '{element_name}' 的原始尺寸")
                QMessageBox.warning(self, '警告', f'无法找到元素 "{element_name}" 的原始尺寸')
                return
                
            original_width, original_height = original_size
            original_ratio = original_width / original_height
            print(f"找到原始尺寸: {original_width}x{original_height}，比例: {original_ratio:.3f}")
            
            # 获取当前预览分辨率
            screen_width, screen_height = self.design_view.get_resolution()
            
            # 获取父元素矩形区域
            parent_element = self.design_view.utils.find_parent_element(element)
            if parent_element:
                parent_rect = self.design_view.utils.parse_area_rect(parent_element, QRect(0, 0, screen_width, screen_height))
            else:
                parent_rect = QRect(0, 0, screen_width, screen_height)
                
            # 获取当前元素的矩形区域
            current_rect = self.design_view.utils.parse_area_rect(element, parent_rect)
            if not current_rect:
                print(f"无法获取元素 '{element_name}' 的当前区域")
                return
                
            # 获取当前尺寸
            current_width = current_rect.width()
            current_height = current_rect.height()
            current_ratio = current_width / current_height if current_height > 0 else 1.0
            print(f"当前尺寸: {current_width}x{current_height}，比例: {current_ratio:.3f}")
            
            # 计算新尺寸 - 保持宽边或长边不变，调整另一边以匹配原始比例
            new_width = current_width
            new_height = current_height
            
            # 如果当前比例小于原始比例（更高），保持高度不变，调整宽度
            if current_ratio < original_ratio:
                # 保持高度不变，根据原始比例调整宽度
                new_width = current_height * original_ratio
                print(f"保持高度 {current_height}，调整宽度为 {new_width:.1f}")
            # 如果当前比例大于原始比例（更宽），保持宽度不变，调整高度
            elif current_ratio > original_ratio:
                # 保持宽度不变，根据原始比例调整高度
                new_height = current_width / original_ratio
                print(f"保持宽度 {current_width}，调整高度为 {new_height:.1f}")
            else:
                print(f"当前比例已经与原始比例相同，无需调整")
            
            # 计算中心位置保持元素居中
            center_x = current_rect.x() + (current_width - new_width) / 2
            center_y = current_rect.y() + (current_height - new_height) / 2
            
            # 调用优化后的元素位置更新函数 - 这会自动更新所有子元素
            self.design_view.utils.update_element_position_optimized(
                element, parent_rect, center_x, center_y, new_width, new_height
            )
            
            # 标记布局为已修改
            self.is_layout_modified = True
            self.update_window_title()
            
            # 更新设计视图
            self.design_view.update()
            
            # 更新属性编辑器（如果当前选中的就是这个元素）
            if self.property_editor.current_element == element:
                self.property_editor.update_properties()
                
            # 更新XML视图
            self.update_xml_view()
            
            # 提示用户
            self.statusBar().showMessage(f'元素 "{element_name}" 已调整到原始比例 {original_width}x{original_height} ({original_ratio:.3f})')
            
        except Exception as e:
            print(f"恢复原始比例时出错: {e}")
            import traceback
            traceback.print_exc()
            QMessageBox.warning(self, '错误', f'恢复原始比例时出错: {str(e)}')
    
    def find_element_original_size(self, element):
        """从图集中查找元素的原始尺寸
        
        参数:
            element: 要查找的元素
            
        返回:
            (width, height) 元组或 None
        """
        # 首先查找元素的Image属性
        image_property = None
        for prop in element.findall('Property'):
            if prop.get('Name') == 'Image':
                image_property = prop.get('Value')
                print(f"找到Image属性: {image_property}")
                break
                
        if not image_property:
            # 如果没有Image属性，检查是否有名称指示图像
            element_name = element.get('Name', '')
            # 如果元素名称包含图像相关信息，尝试提取
            if 'image' in element_name.lower() or 'picture' in element_name.lower():
                print(f"元素名称包含图像相关信息: {element_name}")
                # 在这里可以添加从元素名称中提取图像信息的逻辑
            else:
                print(f"元素 '{element_name}' 没有Image属性")
                return None
        
        # 如果有Image属性，解析图集和图像名称
        # CEGUI格式通常是 set:imageset image:imagename
        if image_property:
            try:
                # 解析Image属性值
                imageset_name = None
                image_name = None
                
                # 处理 "set:XXX image:YYY" 格式
                if "set:" in image_property and "image:" in image_property:
                    parts = image_property.split()
                    for part in parts:
                        if part.startswith("set:"):
                            imageset_name = part[4:]  # 去掉"set:"前缀
                        elif part.startswith("image:"):
                            image_name = part[6:]  # 去掉"image:"前缀
                
                # 处理 "XXX/YYY" 格式
                elif "/" in image_property:
                    parts = image_property.split('/')
                    if len(parts) == 2:
                        imageset_name, image_name = parts
                
                if imageset_name and image_name:
                    print(f"解析出图集 {imageset_name} 和图像 {image_name}")
                    
                    # 直接从xml_handler的imagesets字典中获取图集信息
                    if imageset_name in self.xml_handler.imagesets:
                        imageset = self.xml_handler.imagesets[imageset_name]
                        
                        # 检查图像是否存在于图集中
                        if 'Images' in imageset and image_name in imageset['Images']:
                            image_info = imageset['Images'][image_name]
                            width = image_info['Width']
                            height = image_info['Height']
                            
                            print(f"在图集 {imageset_name} 中找到图像 {image_name}，尺寸: {width}x{height}")
                            
                            # 如果尺寸有效，返回
                            if width > 0 and height > 0:
                                return (width, height)
                            
                print(f"无法从Image属性 '{image_property}' 解析出有效的尺寸信息")
            except Exception as e:
                print(f"解析Image属性时出错: {e}")
                import traceback
                traceback.print_exc()
                
        # 如果找不到图像或出错，尝试使用默认尺寸
        # 可以根据元素类型设置合理的默认值
        element_type = element.get('Type', '')
        if element_type == 'StaticImage':
            return (64, 64)  # 静态图像默认大小
        elif element_type == 'StaticText':
            return (200, 30)  # 文本默认大小
        elif element_type == 'Button':
            return (100, 30)  # 按钮默认大小
        elif element_type == 'FrameWindow':
            return (300, 200)  # 窗口默认大小
        elif element_type == 'DefaultWindow':
            # 对于默认窗口，使用较大的尺寸
            current_resolution = self.design_view.get_resolution()
            return (current_resolution[0] // 2, current_resolution[1] // 2)
            
        # 最终默认尺寸
        print(f"使用元素 '{element.get('Name', '')}' 的默认尺寸 100x100")
        return (100, 100)

    def adjust_aspect_ratio(self, element):
        """调整元素比例，保持高度不变，宽度变为原来的4分之3
        
        参数:
            element: 要调整的元素
        """
        if not element:
            print("错误: 调整比例的元素为空")
            return
            
        # 获取元素名称用于日志
        element_name = element.get('Name', '未命名')
        print(f"调整元素 '{element_name}' 的宽度为高度的4/3")
        
        try:
            # 获取当前预览分辨率
            screen_width, screen_height = self.design_view.get_resolution()
            
            # 获取父元素矩形区域
            parent_element = self.design_view.utils.find_parent_element(element)
            if parent_element:
                parent_rect = self.design_view.utils.parse_area_rect(parent_element, QRect(0, 0, screen_width, screen_height))
            else:
                parent_rect = QRect(0, 0, screen_width, screen_height)
                
            # 获取当前元素的矩形区域
            current_rect = self.design_view.utils.parse_area_rect(element, parent_rect)
            if not current_rect:
                print(f"无法获取元素 '{element_name}' 的当前区域")
                return
                
            # 获取当前尺寸
            current_width = current_rect.width()
            current_height = current_rect.height()
            print(f"当前尺寸: {current_width}x{current_height}")
            
            # 保持高度不变，宽度变为原来的4分之3
            new_width = current_width * 0.75
            new_height = current_height
            print(f"新尺寸: {new_width}x{new_height}，宽度变为原来的4分之3")
            
            # 保持中心位置不变
            center_x = current_rect.x() + (current_width - new_width) / 2
            center_y = current_rect.y()
            
            # 调用优化后的元素位置更新函数 - 这会自动更新所有子元素
            self.design_view.utils.update_element_position_optimized(
                element, parent_rect, center_x, center_y, new_width, new_height
            )
            
            # 标记布局为已修改
            self.is_layout_modified = True
            self.update_window_title()
            
            # 更新设计视图
            self.design_view.update()
            
            # 更新属性编辑器（如果当前选中的就是这个元素）
            if self.property_editor.current_element == element:
                self.property_editor.update_properties()
                
            # 更新XML视图
            self.update_xml_view()
            
            # 提示用户
            self.statusBar().showMessage(f'元素 "{element_name}" 的宽度已调整为原来的4分之3')
            
        except Exception as e:
            print(f"调整比例时出错: {e}")
            import traceback
            traceback.print_exc()
            QMessageBox.warning(self, '错误', f'调整比例时出错: {str(e)}')

    def show_coordinate_converter(self):
        """显示坐标转换器对话框"""
        dialog = CoordinateConverterDialog(self)
        
        # 如果有选中的元素，预填充其坐标
        if self.design_view.selected_element:
            element = self.design_view.selected_element
            # 查找UnifiedAreaRect属性
            for prop in element.findall('Property'):
                if prop.get('Name') == 'UnifiedAreaRect':
                    # 解析UnifiedAreaRect值
                    value = prop.get('Value')
                    try:
                        # 使用设计视图的工具类解析区域值
                        x1, y1, x2, y2 = self.design_view.utils.parse_unified_area_rect_string(value)
                        
                        # 设置相对值
                        dialog.x1_relative.setValue(x1)
                        dialog.y1_relative.setValue(y1)
                        dialog.x2_relative.setValue(x2)
                        dialog.y2_relative.setValue(y2)
                        
                        # 转换为绝对坐标并设置
                        width, height = self.design_view.get_resolution()
                        dialog.x1_absolute.setValue(int(x1 * width))
                        dialog.y1_absolute.setValue(int(y1 * height))
                        dialog.x2_absolute.setValue(int(x2 * width))
                        dialog.y2_absolute.setValue(int(y2 * height))
                        
                        # 更新UnifiedAreaRect显示
                        dialog.update_unified_area_rect()
                    except Exception as e:
                        print(f"解析UnifiedAreaRect时出错: {e}")
                    break
        
        # 显示对话框
        dialog.exec_()

    def show_element_coordinates(self, element):
        """显示元素的坐标信息"""
        if not element:
            return
            
        # 获取元素的UnifiedAreaRect属性
        area_rect = None
        for prop in element.findall('Property'):
            if prop.get('Name') == 'UnifiedAreaRect':
                area_rect = prop.get('Value')
                break
                
        if not area_rect:
            QMessageBox.warning(self, '警告', '该元素没有UnifiedAreaRect属性')
            return
            
        try:
            # 获取当前分辨率
            width, height = self.design_view.get_resolution()
            
            # 解析UnifiedAreaRect值
            x1, y1, x2, y2 = self.design_view.utils.parse_unified_area_rect_string(area_rect)
            
            # 计算绝对坐标
            abs_x1 = int(x1 * width)
            abs_y1 = int(y1 * height)
            abs_x2 = int(x2 * width)
            abs_y2 = int(y2 * height)
            
            # 计算宽度和高度
            abs_width = abs_x2 - abs_x1
            abs_height = abs_y2 - abs_y1
            
            # 准备显示信息
            element_name = element.get('Name', '未命名')
            info = f"元素: {element_name}\n\n"
            info += f"当前分辨率: {width}x{height}\n\n"
            info += f"相对坐标: \n"
            info += f"  左上角: ({x1:.6f}, {y1:.6f})\n"
            info += f"  右下角: ({x2:.6f}, {y2:.6f})\n\n"
            info += f"绝对坐标 (像素): \n"
            info += f"  左上角: ({abs_x1}, {abs_y1})\n"
            info += f"  右下角: ({abs_x2}, {abs_y2})\n"
            info += f"  宽度: {abs_width}  高度: {abs_height}\n\n"
            info += f"UnifiedAreaRect: \n{area_rect}"
            
            # 显示信息对话框
            QMessageBox.information(self, '坐标信息', info)
            
        except Exception as e:
            QMessageBox.warning(self, '错误', f'解析坐标信息时出错: {str(e)}')
    
    def copy_relative_coordinates(self, element):
        """复制元素的相对坐标到剪贴板"""
        if not element:
            return
            
        # 获取元素的UnifiedAreaRect属性
        area_rect = None
        for prop in element.findall('Property'):
            if prop.get('Name') == 'UnifiedAreaRect':
                area_rect = prop.get('Value')
                break
                
        if not area_rect:
            QMessageBox.warning(self, '警告', '该元素没有UnifiedAreaRect属性')
            return
            
        try:
            # 直接复制相对坐标(UnifiedAreaRect)到剪贴板
            QApplication.clipboard().setText(area_rect)
            self.statusBar().showMessage(f'已复制相对坐标到剪贴板: {area_rect}')
            
        except Exception as e:
            QMessageBox.warning(self, '错误', f'复制相对坐标时出错: {str(e)}')
    
    def copy_absolute_coordinates(self, element):
        """复制元素的绝对坐标到剪贴板，包括所有子元素"""
        if not element:
            return
            
        # 获取当前分辨率
        width, height = self.design_view.get_resolution()
        
        # 收集所有坐标信息
        coords_info = []
        self._collect_absolute_coordinates(element, 0, width, height, coords_info)
        
        # 格式化为文本
        if coords_info:
            # 拼接全部信息
            text = "\n".join(coords_info)
            
            # 复制到剪贴板
            QApplication.clipboard().setText(text)
            self.statusBar().showMessage(f'已复制所有元素的绝对坐标到剪贴板')
            
            # 同时显示信息对话框
            scroll_area = QScrollArea()
            scroll_area.setWidgetResizable(True)
            text_edit = QTextEdit()
            text_edit.setReadOnly(True)
            text_edit.setText(text)
            scroll_area.setWidget(text_edit)
            
            dialog = QDialog(self)
            dialog.setWindowTitle('元素绝对坐标')
            dialog.resize(600, 400)
            
            layout = QVBoxLayout(dialog)
            layout.addWidget(QLabel(f"当前分辨率: {width}x{height}"))
            layout.addWidget(scroll_area)
            
            button_layout = QHBoxLayout()
            close_button = QPushButton("关闭")
            close_button.clicked.connect(dialog.close)
            button_layout.addWidget(close_button)
            layout.addLayout(button_layout)
            
            dialog.exec_()
        else:
            QMessageBox.warning(self, '警告', '无法获取坐标信息')
    
    def _collect_absolute_coordinates(self, element, level, width, height, result):
        """递归收集元素及其子元素的绝对坐标信息
        
        参数:
            element: 当前元素
            level: 当前层级(用于缩进)
            width, height: 当前分辨率
            result: 结果列表
        """
        # 获取元素的基本信息
        element_name = element.get('Name', '未命名')
        element_type = element.get('Type', '未知类型')
        indent = "  " * level
        
        # 获取UnifiedAreaRect属性
        area_rect = None
        for prop in element.findall('Property'):
            if prop.get('Name') == 'UnifiedAreaRect':
                area_rect = prop.get('Value')
                break
        
        if area_rect:
            try:
                # 解析UnifiedAreaRect值
                x1, y1, x2, y2 = self.design_view.utils.parse_unified_area_rect_string(area_rect)
                
                # 计算绝对坐标
                abs_x1 = int(x1 * width)
                abs_y1 = int(y1 * height)
                abs_x2 = int(x2 * width)
                abs_y2 = int(y2 * height)
                abs_width = abs_x2 - abs_x1
                abs_height = abs_y2 - abs_y1
                
                # 添加元素信息
                element_info = f"{indent}元素: {element_name} (类型: {element_type})"
                result.append(element_info)
                result.append(f"{indent}  位置: 左上({abs_x1}, {abs_y1}), 右下({abs_x2}, {abs_y2})")
                result.append(f"{indent}  尺寸: 宽度={abs_width}, 高度={abs_height}")
                result.append(f"{indent}  相对值: {{x1={x1:.6f}, y1={y1:.6f}, x2={x2:.6f}, y2={y2:.6f}}}")
                result.append("")
            except Exception as e:
                result.append(f"{indent}元素: {element_name} - 解析坐标出错: {e}")
                result.append("")
        else:
            result.append(f"{indent}元素: {element_name} - 无UnifiedAreaRect属性")
            result.append("")
        
        # 递归处理所有子元素
        for child in element.findall('Window'):
            self._collect_absolute_coordinates(child, level + 1, width, height, result)

    def convert_to_absolute_coordinates(self, element):
        """将元素及其子元素的坐标转换为绝对坐标格式"""
        if not element:
            return
            
        # 获取当前分辨率
        width, height = self.design_view.get_resolution()
        
        # 确认是否继续
        reply = QMessageBox.question(
            self, 
            '确认转换',
            f'确定要将元素"{element.get("Name", "未命名")}"及其所有子元素转换为绝对坐标格式吗？\n\n'
            f'注意：这将修改所有元素的坐标属性，使它们固定在当前位置。\n'
            f'子元素的坐标将相对于父元素的尺寸计算。\n'
            f'此操作可能不可逆，是否继续？',
            QMessageBox.Yes | QMessageBox.No
        )
        
        if reply == QMessageBox.No:
            return
            
        # 执行转换
        # 确定元素的父区域，如果是顶层元素使用全局分辨率
        parent_element = self.design_view.utils.find_parent_element(element)
        if parent_element:
            # 获取父元素的矩形区域
            parent_rect = self.design_view.utils.parse_area_rect(
                parent_element, 
                QRect(0, 0, width, height)
            )
            # 如果无法获取父矩形，使用全局分辨率
            if not parent_rect:
                parent_rect = QRect(0, 0, width, height)
        else:
            # 顶层元素，使用全局分辨率
            parent_rect = QRect(0, 0, width, height)
        
        # 开始递归转换，从当前元素开始
        modified_count = self._convert_element_coordinates(element, parent_rect)
        
        if modified_count > 0:
            # 标记布局为已修改
            self.is_layout_modified = True
            self.update_window_title()
            
            # 更新界面
            self.design_view.update()
            self.update_xml_view()
            
            # 如果属性编辑器当前选中的是这个元素，更新属性编辑器
            if self.property_editor.current_element == element:
                self.property_editor.update_properties()
                
            # 显示成功消息
            self.statusBar().showMessage(f'已将 {modified_count} 个元素转换为绝对坐标格式')
        else:
            QMessageBox.warning(self, '转换失败', '转换过程中没有修改任何元素')

    def convert_to_relative_coordinates(self, element):
        """将元素及其子元素的绝对坐标转换回相对坐标格式"""
        if not element:
            return
            
        # 获取当前分辨率，用于计算最顶层元素
        width, height = self.design_view.get_resolution()
        
        # 确认是否继续
        reply = QMessageBox.question(
            self, 
            '确认转换',
            f'确定要将元素"{element.get("Name", "未命名")}"及其所有子元素还原为相对坐标格式吗？\n\n'
            f'注意：这将重置所有元素的坐标为标准相对格式。',
            QMessageBox.Yes | QMessageBox.No
        )
        
        if reply == QMessageBox.No:
            return
        
        # 确定元素的父区域，如果是顶层元素使用全局分辨率
        parent_element = self.design_view.utils.find_parent_element(element)
        if parent_element:
            # 获取父元素的矩形区域
            parent_rect = self.design_view.utils.parse_area_rect(
                parent_element, 
                QRect(0, 0, width, height)
            )
            # 如果无法获取父矩形，使用全局分辨率
            if not parent_rect:
                parent_rect = QRect(0, 0, width, height)
        else:
            # 顶层元素，使用全局分辨率
            parent_rect = QRect(0, 0, width, height)
            
        # 执行转换
        modified_count = self._restore_relative_coordinates(element, parent_rect)
        
        if modified_count > 0:
            # 标记布局为已修改
            self.is_layout_modified = True
            self.update_window_title()
            
            # 更新界面
            self.design_view.update()
            self.update_xml_view()
            
            # 如果属性编辑器当前选中的是这个元素，更新属性编辑器
            if self.property_editor.current_element == element:
                self.property_editor.update_properties()
                
            # 显示成功消息
            self.statusBar().showMessage(f'已将 {modified_count} 个元素还原为相对坐标格式')
        else:
            QMessageBox.warning(self, '转换失败', '转换过程中没有修改任何元素')
    
    def _convert_element_coordinates(self, element, parent_rect):
        """递归转换元素及其子元素的坐标为绝对坐标格式
        
        参数:
            element: 当前元素
            parent_rect: 父元素的矩形区域
            
        返回:
            修改的元素数量
        """
        modified_count = 0
        
        # 获取元素的UnifiedAreaRect属性
        area_rect_prop = None
        for prop in element.findall('Property'):
            if prop.get('Name') == 'UnifiedAreaRect':
                area_rect_prop = prop
                break
                
        if area_rect_prop is not None:
            try:
                area_rect = area_rect_prop.get('Value')
                
                # 解析UnifiedAreaRect值
                x1, y1, x2, y2 = self.design_view.utils.parse_unified_area_rect_string(area_rect)
                
                # 计算元素在父窗口中的实际像素位置
                abs_x1 = int(x1 * parent_rect.width()) + parent_rect.x()
                abs_y1 = int(y1 * parent_rect.height()) + parent_rect.y()
                abs_x2 = int(x2 * parent_rect.width()) + parent_rect.x()
                abs_y2 = int(y2 * parent_rect.height()) + parent_rect.y()
                
                # 计算相对于父窗口左上角的偏移像素
                rel_x1 = abs_x1 - parent_rect.x()
                rel_y1 = abs_y1 - parent_rect.y()
                rel_x2 = abs_x2 - parent_rect.x()
                rel_y2 = abs_y2 - parent_rect.y()
                
                # 使用CEGUI的像素偏移语法
                # {{0,pixel_x1},{0,pixel_y1},{0,pixel_x2},{0,pixel_y2}}
                new_value = f"{{{{0,{rel_x1}}},{{0,{rel_y1}}},{{0,{rel_x2}}},{{0,{rel_y2}}}}}"
                area_rect_prop.set('Value', new_value)
                modified_count += 1
                
                # 获取当前元素的实际区域大小，用于子元素计算
                element_rect = QRect(abs_x1, abs_y1, abs_x2 - abs_x1, abs_y2 - abs_y1)
                
                # 递归处理所有子元素，使用当前元素的实际区域作为新的父区域
                for child in element.findall('Window'):
                    modified_count += self._convert_element_coordinates(child, element_rect)
                    
            except Exception as e:
                print(f"转换元素坐标出错: {e}")
                
                # 尽管出错，仍尝试处理子元素
                # 获取元素的区域，用于子元素转换
                element_rect = self.design_view.utils.parse_area_rect(element, parent_rect)
                if not element_rect:
                    element_rect = parent_rect  # 如果无法获取，使用父区域
                
                # 处理子元素
                for child in element.findall('Window'):
                    modified_count += self._convert_element_coordinates(child, element_rect)
        else:
            # 如果没有坐标属性，仍尝试处理子元素
            # 获取元素的区域，用于子元素转换
            element_rect = self.design_view.utils.parse_area_rect(element, parent_rect)
            if not element_rect:
                element_rect = parent_rect  # 如果无法获取，使用父区域
            
            # 处理子元素
            for child in element.findall('Window'):
                modified_count += self._convert_element_coordinates(child, element_rect)
            
        return modified_count
    
    def _restore_relative_coordinates(self, element, parent_rect):
        """递归将元素及其子元素从绝对坐标格式还原为相对坐标格式
        
        参数:
            element: 当前元素
            parent_rect:.父元素的矩形区域
            
        返回:
            修改的元素数量
        """
        modified_count = 0
        
        # 获取元素的UnifiedAreaRect属性
        area_rect_prop = None
        for prop in element.findall('Property'):
            if prop.get('Name') == 'UnifiedAreaRect':
                area_rect_prop = prop
                break
                
        if area_rect_prop is not None:
            try:
                area_rect = area_rect_prop.get('Value')
                
                # 检查是否是像素偏移格式
                is_pixel_format = False
                pixel_values = [0, 0, 0, 0]
                
                import re
                pattern = r"\{\{[\d\.-]+,([\d\.-]+)\},\{[\d\.-]+,([\d\.-]+)\},\{[\d\.-]+,([\d\.-]+)\},\{[\d\.-]+,([\d\.-]+)\}\}"
                match = re.match(pattern, area_rect)
                
                if match and any(float(match.group(i)) > 0 for i in range(1, 5)):
                    is_pixel_format = True
                    
                    # 如果是像素格式，解析像素值
                    for i in range(4):
                        pixel_values[i] = float(match.group(i+1))
                    
                if is_pixel_format:
                    # 如果是像素格式，转换为相对格式
                    # 父窗口的宽度和高度
                    parent_width = parent_rect.width()
                    parent_height = parent_rect.height()
                    
                    if parent_width > 0 and parent_height > 0:
                        # 计算相对值
                        rel_x1 = pixel_values[0] / parent_width
                        rel_y1 = pixel_values[1] / parent_height
                        rel_x2 = pixel_values[2] / parent_width
                        rel_y2 = pixel_values[3] / parent_height
                        
                        # 设置为标准相对格式
                        new_value = f"{{{{{rel_x1:.6f},0}},{{{rel_y1:.6f},0}},{{{rel_x2:.6f},0}},{{{rel_y2:.6f},0}}}}"
                        area_rect_prop.set('Value', new_value)
                        modified_count += 1
                    else:
                        print(f"父窗口尺寸无效: {parent_width}x{parent_height}")
                else:
                    # 如果不是像素格式，解析当前相对值
                    x1, y1, x2, y2 = self.design_view.utils.parse_unified_area_rect_string(area_rect)
                    
                    # 规范化小数位数
                    new_value = f"{{{{{x1:.6f},0}},{{{y1:.6f},0}},{{{x2:.6f},0}},{{{y2:.6f},0}}}}"
                    if new_value != area_rect:
                        area_rect_prop.set('Value', new_value)
                        modified_count += 1
                
                # 计算元素的实际区域，用于子元素计算
                element_rect = self.design_view.utils.parse_area_rect(element, parent_rect)
                if not element_rect:
                    # 如果无法获取元素区域，使用父区域
                    element_rect = parent_rect
                    
                # 递归处理子元素
                for child in element.findall('Window'):
                    modified_count += self._restore_relative_coordinates(child, element_rect)
                    
            except Exception as e:
                print(f"还原元素坐标出错: {e}")
                
                # 尽管出错，仍尝试处理子元素
                element_rect = self.design_view.utils.parse_area_rect(element, parent_rect)
                if not element_rect:
                    element_rect = parent_rect
                
                # 处理子元素
                for child in element.findall('Window'):
                    modified_count += self._restore_relative_coordinates(child, element_rect)
        else:
            # 如果元素没有坐标属性，仍处理其子元素
            element_rect = self.design_view.utils.parse_area_rect(element, parent_rect)
            if not element_rect:
                element_rect = parent_rect
                
            # 处理子元素
            for child in element.findall('Window'):
                modified_count += self._restore_relative_coordinates(child, element_rect)
                
        return modified_count

    def on_layout_processed_changed(self, item, column):
        """处理布局文件处理状态变化"""
        # 仅处理第一列（已处理状态）的变化
        if column == 0:
            layout_info = item.data(0, Qt.UserRole)
            if layout_info:
                file_path = layout_info['path']
                is_processed = item.checkState(0) == Qt.Checked
                # 更新配置
                self.config_manager.set_layout_processed(file_path, is_processed)
                
                # 更新状态栏提示
                status_message = f"已将 {layout_info['name']} 标记为{'已处理' if is_processed else '未处理'}"
                self.statusBar().showMessage(status_message, 3000)  # 显示3秒

    def update_selected_file_in_list(self):
        """在文件列表中高亮显示当前打开的文件"""
        if not hasattr(self, 'layouts_list') or not self.current_layout_file:
            return
            
        # 取消所有项的选中状态
        for i in range(self.layouts_list.topLevelItemCount()):
            item = self.layouts_list.topLevelItem(i)
            item.setSelected(False)
        
        # 查找并选中当前打开的文件
        for i in range(self.layouts_list.topLevelItemCount()):
            item = self.layouts_list.topLevelItem(i)
            layout_info = item.data(0, Qt.UserRole)
            if layout_info and layout_info['path'] == self.current_layout_file:
                item.setSelected(True)
                # 确保选中的项可见
                self.layouts_list.scrollToItem(item)
                break

    def select_element(self, element, update_tree=True):
        """统一的元素选择方法
        
        参数:
            element: 要选择的元素
            update_tree: 是否需要更新元素树的选择状态
        """
        if not element:
            return
            
        # 更新设计视图中的选择
        self.design_view.set_selected_element(element)
        
        # 更新属性编辑器
        self.property_editor.set_element(element)
        
        # 如果需要，更新元素树的选择状态
        if update_tree:
            self.update_tree_selection(element)
            
        # 更新状态栏信息
        element_name = element.get('Name', '未命名')
        element_type = element.get('Type', '未知类型')
        self.statusBar().showMessage(f'已选择元素: {element_name} (类型: {element_type})')

    def update_tree_selection(self, element):
        """更新元素树的选择状态，使其与当前选择的元素一致
        
        参数:
            element: 要在树中选择的元素
        """
        def find_item_for_element(root_item, target_element):
            # 检查当前项
            if root_item.data(0, Qt.UserRole) == target_element:
                return root_item
                
            # 递归检查子项
            for i in range(root_item.childCount()):
                child_item = root_item.child(i)
                found = find_item_for_element(child_item, target_element)
                if found:
                    return found
                    
            return None
        
        # 清除所有选择
        self.element_tree.clearSelection()
        
        # 从根项开始搜索
        for i in range(self.element_tree.topLevelItemCount()):
            root_item = self.element_tree.topLevelItem(i)
            item = find_item_for_element(root_item, element)
            if item:
                # 选中找到的项
                item.setSelected(True)
                # 确保项可见
                self.element_tree.scrollToItem(item)
                break

    def create_shortcuts(self):
        """创建全局快捷键"""
        # 创建宽度调整为4分之3的快捷键
        self.shortcut_adjust_ratio = QShortcut('S', self)
        self.shortcut_adjust_ratio.activated.connect(self.on_shortcut_adjust_ratio)
        
    def on_shortcut_adjust_ratio(self):
        """响应S键快捷键，将当前选中元素的宽度调整为4分之3"""
        if hasattr(self, 'design_view') and self.design_view.selected_element:
            element = self.design_view.selected_element
            self.adjust_aspect_ratio(element)
            self.statusBar().showMessage(f'已使用快捷键调整元素 "{element.get("Name", "未命名")}" 的宽度为4分之3')
        else:
            self.statusBar().showMessage('请先选择一个元素')

    def toggle_coordinate_mode(self):
        """切换坐标模式"""
        self.coordinate_mode = 'absolute' if self.coordinate_mode == 'relative' else 'relative'
        
        # 同步菜单和工具栏状态
        is_absolute = self.coordinate_mode == 'absolute'
        self.coordinate_mode_action.setChecked(is_absolute)
        self.coordinate_mode_checkbox.setChecked(is_absolute)
        
        # 更新设计视图的坐标模式
        if hasattr(self, 'design_view'):
            self.design_view.set_coordinate_mode(self.coordinate_mode)
        
        # 更新属性编辑器的显示
        if hasattr(self, 'property_editor') and self.property_editor.current_element:
            self.property_editor.set_coordinate_mode(self.coordinate_mode)
            self.property_editor.update_properties()
        
        # 显示状态信息
        mode_text = "绝对像素坐标" if is_absolute else "相对坐标"
        self.statusBar().showMessage(f'已切换到{mode_text}模式')
        
    def get_coordinate_mode(self):
        """获取当前坐标模式"""
        return self.coordinate_mode

class CoordinateConverterDialog(QDialog):
    """坐标转换器对话框，用于在绝对坐标和相对坐标之间转换"""
    
    def __init__(self, parent=None):
        super(CoordinateConverterDialog, self).__init__(parent)
        self.parent = parent
        self.init_ui()
        
    def init_ui(self):
        """初始化UI"""
        self.setWindowTitle('坐标转换器')
        self.setMinimumWidth(500)
        
        # 创建主布局
        main_layout = QVBoxLayout(self)
        
        # 当前分辨率信息
        resolution_layout = QHBoxLayout()
        resolution_layout.addWidget(QLabel('当前预览分辨率:'))
        
        # 获取当前分辨率
        if self.parent and hasattr(self.parent, 'design_view'):
            width, height = self.parent.design_view.get_resolution()
            resolution_text = f"{width}x{height}"
        else:
            resolution_text = "未知"
            width, height = 800, 600  # 默认分辨率
            
        self.resolution_label = QLabel(resolution_text)
        resolution_layout.addWidget(self.resolution_label)
        resolution_layout.addStretch()
        
        # 添加分辨率信息到主布局
        main_layout.addLayout(resolution_layout)
        
        # 创建转换表单布局
        form_layout = QGridLayout()
        
        # 左上角坐标
        form_layout.addWidget(QLabel('左上角:'), 0, 0)
        
        # X1 - 左上角X坐标
        form_layout.addWidget(QLabel('X1:'), 1, 0)
        self.x1_absolute = QSpinBox()
        self.x1_absolute.setRange(0, 9999)
        self.x1_absolute.setValue(0)
        form_layout.addWidget(self.x1_absolute, 1, 1)
        
        form_layout.addWidget(QLabel('相对值:'), 1, 2)
        self.x1_relative = QDoubleSpinBox()
        self.x1_relative.setRange(0, 1)
        self.x1_relative.setDecimals(6)
        self.x1_relative.setSingleStep(0.01)
        form_layout.addWidget(self.x1_relative, 1, 3)
        
        # Y1 - 左上角Y坐标
        form_layout.addWidget(QLabel('Y1:'), 2, 0)
        self.y1_absolute = QSpinBox()
        self.y1_absolute.setRange(0, 9999)
        self.y1_absolute.setValue(0)
        form_layout.addWidget(self.y1_absolute, 2, 1)
        
        form_layout.addWidget(QLabel('相对值:'), 2, 2)
        self.y1_relative = QDoubleSpinBox()
        self.y1_relative.setRange(0, 1)
        self.y1_relative.setDecimals(6)
        self.y1_relative.setSingleStep(0.01)
        form_layout.addWidget(self.y1_relative, 2, 3)
        
        # 右下角坐标
        form_layout.addWidget(QLabel('右下角:'), 3, 0)
        
        # X2 - 右下角X坐标
        form_layout.addWidget(QLabel('X2:'), 4, 0)
        self.x2_absolute = QSpinBox()
        self.x2_absolute.setRange(0, 9999)
        self.x2_absolute.setValue(width)
        form_layout.addWidget(self.x2_absolute, 4, 1)
        
        form_layout.addWidget(QLabel('相对值:'), 4, 2)
        self.x2_relative = QDoubleSpinBox()
        self.x2_relative.setRange(0, 1)
        self.x2_relative.setDecimals(6)
        self.x2_relative.setValue(1.0)
        self.x2_relative.setSingleStep(0.01)
        form_layout.addWidget(self.x2_relative, 4, 3)
        
        # Y2 - 右下角Y坐标
        form_layout.addWidget(QLabel('Y2:'), 5, 0)
        self.y2_absolute = QSpinBox()
        self.y2_absolute.setRange(0, 9999)
        self.y2_absolute.setValue(height)
        form_layout.addWidget(self.y2_absolute, 5, 1)
        
        form_layout.addWidget(QLabel('相对值:'), 5, 2)
        self.y2_relative = QDoubleSpinBox()
        self.y2_relative.setRange(0, 1)
        self.y2_relative.setDecimals(6)
        self.y2_relative.setValue(1.0)
        self.y2_relative.setSingleStep(0.01)
        form_layout.addWidget(self.y2_relative, 5, 3)
        
        # 添加表单布局到主布局
        main_layout.addLayout(form_layout)
        
        # 添加转换按钮
        button_layout = QHBoxLayout()
        
        self.absolute_to_relative_btn = QPushButton('绝对→相对')
        self.absolute_to_relative_btn.clicked.connect(self.convert_absolute_to_relative)
        button_layout.addWidget(self.absolute_to_relative_btn)
        
        self.relative_to_absolute_btn = QPushButton('相对→绝对')
        self.relative_to_absolute_btn.clicked.connect(self.convert_relative_to_absolute)
        button_layout.addWidget(self.relative_to_absolute_btn)
        
        # 添加按钮布局到主布局
        main_layout.addLayout(button_layout)
        
        # 添加生成的UnifiedAreaRect显示
        main_layout.addWidget(QLabel('生成的UnifiedAreaRect格式:'))
        self.unified_area_rect = QLineEdit()
        self.unified_area_rect.setReadOnly(True)
        main_layout.addWidget(self.unified_area_rect)
        
        # 添加复制和应用按钮
        copy_apply_layout = QHBoxLayout()
        
        copy_button = QPushButton('复制到剪贴板')
        copy_button.clicked.connect(self.copy_to_clipboard)
        copy_apply_layout.addWidget(copy_button)
        
        apply_button = QPushButton('应用到所选元素')
        apply_button.clicked.connect(self.apply_to_selected)
        copy_apply_layout.addWidget(apply_button)
        
        main_layout.addLayout(copy_apply_layout)
        
        # 添加关闭按钮
        close_button = QPushButton('关闭')
        close_button.clicked.connect(self.close)
        main_layout.addWidget(close_button)
        
    def convert_absolute_to_relative(self):
        """将绝对坐标转换为相对坐标"""
        # 获取当前分辨率
        width, height = self.get_current_resolution()
        
        # 获取绝对坐标
        x1 = self.x1_absolute.value()
        y1 = self.y1_absolute.value()
        x2 = self.x2_absolute.value()
        y2 = self.y2_absolute.value()
        
        # 转换为相对坐标
        if width > 0 and height > 0:
            self.x1_relative.setValue(x1 / width)
            self.y1_relative.setValue(y1 / height)
            self.x2_relative.setValue(x2 / width)
            self.y2_relative.setValue(y2 / height)
            
            # 更新UnifiedAreaRect格式
            self.update_unified_area_rect()
    
    def convert_relative_to_absolute(self):
        """将相对坐标转换为绝对坐标"""
        # 获取当前分辨率
        width, height = self.get_current_resolution()
        
        # 获取相对坐标
        x1 = self.x1_relative.value()
        y1 = self.y1_relative.value()
        x2 = self.x2_relative.value()
        y2 = self.y2_relative.value()
        
        # 转换为绝对坐标
        self.x1_absolute.setValue(int(x1 * width))
        self.y1_absolute.setValue(int(y1 * height))
        self.x2_absolute.setValue(int(x2 * width))
        self.y2_absolute.setValue(int(y2 * height))
        
        # 更新UnifiedAreaRect格式
        self.update_unified_area_rect()
    
    def update_unified_area_rect(self):
        """更新UnifiedAreaRect格式字符串"""
        x1 = self.x1_relative.value()
        y1 = self.y1_relative.value()
        x2 = self.x2_relative.value()
        y2 = self.y2_relative.value()
        
        # 格式化为CEGUI的UnifiedAreaRect格式
        unified_rect = f"{{{{{x1:.6f},0}},{{{y1:.6f},0}},{{{x2:.6f},0}},{{{y2:.6f},0}}}}"
        self.unified_area_rect.setText(unified_rect)
    
    def get_current_resolution(self):
        """获取当前分辨率"""
        if self.parent and hasattr(self.parent, 'design_view'):
            return self.parent.design_view.get_resolution()
        else:
            return 800, 600  # 默认分辨率
    
    def copy_to_clipboard(self):
        """复制UnifiedAreaRect到剪贴板"""
        QApplication.clipboard().setText(self.unified_area_rect.text())
        if self.parent:
            self.parent.statusBar().showMessage('已复制坐标到剪贴板')
    
    def apply_to_selected(self):
        """将生成的UnifiedAreaRect应用到当前选中的元素"""
        if not self.parent or not hasattr(self.parent, 'design_view'):
            return
            
        # 获取当前选中的元素
        selected_element = self.parent.design_view.selected_element
        if not selected_element:
            QMessageBox.warning(self, '警告', '请先在元素树中选择一个元素')
            return
            
        # 获取生成的UnifiedAreaRect值
        unified_rect = self.unified_area_rect.text()
        if not unified_rect:
            return
            
        # 更新属性
        for prop in selected_element.findall('Property'):
            if prop.get('Name') == 'UnifiedAreaRect':
                prop.set('Value', unified_rect)
                break
        else:
            # 如果没有找到UnifiedAreaRect属性，创建一个新的
            prop = ET.Element('Property')
            prop.set('Name', 'UnifiedAreaRect')
            prop.set('Value', unified_rect)
            selected_element.append(prop)
            
        # 更新UI
        self.parent.is_layout_modified = True
        self.parent.update_window_title()
        self.parent.design_view.update()
        self.parent.update_xml_view()
        
        # 如果属性编辑器中显示的是当前元素，更新属性编辑器
        if self.parent.property_editor.current_element == selected_element:
            self.parent.property_editor.update_properties()
            
        self.parent.statusBar().showMessage(f'已应用新位置坐标到元素: {selected_element.get("Name", "未命名")}')

class LayoutCanvasUtils:
    """布局画布工具类"""
    
    def __init__(self, canvas):
        self.canvas = canvas
    
    # ... existing code ...
    
    def parse_unified_area_rect_string(self, area_rect_string):
        """解析UnifiedAreaRect字符串，返回四个相对坐标值
        
        参数:
            area_rect_string: 格式为 "{{x1,x1_offset},{y1,y1_offset},{x2,x2_offset},{y2,y2_offset}}"
            
        返回:
            (x1, y1, x2, y2): 四个相对坐标值的元组
        """
        try:
            # 去除所有空格
            area_rect_string = area_rect_string.replace(' ', '')
            
            # 使用正则表达式解析字符串
            import re
            pattern = r"\{\{([\d\.-]+),[\d\.-]+\},\{([\d\.-]+),[\d\.-]+\},\{([\d\.-]+),[\d\.-]+\},\{([\d\.-]+),[\d\.-]+\}\}"
            match = re.match(pattern, area_rect_string)
            
            if match:
                x1 = float(match.group(1))
                y1 = float(match.group(2))
                x2 = float(match.group(3))
                y2 = float(match.group(4))
                return (x1, y1, x2, y2)
            else:
                # 如果正则匹配失败，尝试手动解析
                # 删除大括号和空格
                clean_str = area_rect_string.strip('{}')
                parts = clean_str.split('},{')
                
                if len(parts) == 4:
                    x1 = float(parts[0].strip('{').split(',')[0])
                    y1 = float(parts[1].split(',')[0])
                    x2 = float(parts[2].split(',')[0])
                    y2 = float(parts[3].split(',')[0])
                    return (x1, y1, x2, y2)
                
            # 如果无法解析，返回默认值
            print(f"无法解析UnifiedAreaRect: {area_rect_string}")
            return (0.0, 0.0, 1.0, 1.0)
        except Exception as e:
            print(f"解析UnifiedAreaRect时出错: {e}")
            return (0.0, 0.0, 1.0, 1.0)

# ... existing code ...

if __name__ == "__main__":
    try:
        print("开始初始化应用程序...")
        app = QApplication(sys.argv)
        print("QApplication创建成功.")
        
        print("创建主窗口...")
        window = MainWindow()
        print("主窗口创建成功，显示窗口.")
        window.show()
        
        print("进入应用程序事件循环...")
        sys.exit(app.exec_())
    except Exception as e:
        print(f"运行时出错: {e}")
        traceback.print_exc()
        input("按任意键退出...")
        sys.exit(1) 